diff --git a/src/constants/query-strings.js b/src/constants/query-strings.js index 4a5c47943..9fb379836 100644 --- a/src/constants/query-strings.js +++ b/src/constants/query-strings.js @@ -36,6 +36,7 @@ const queryStrings = { VIN_SELECTION: "vinselection", SERVICE_PACKAGE: "servicepackage", NUMBER_OF_CHIPS: "numberofchips", + LOG: "log", UTM_SOURCE: "_source", UTM_MEDIUM: "_medium", UTM_CAMPAIGN: "_campaign", diff --git a/src/helpers/date-helper.js b/src/helpers/date-helper.js index b5afc535c..59ffa5745 100644 --- a/src/helpers/date-helper.js +++ b/src/helpers/date-helper.js @@ -8,6 +8,10 @@ export function getDateDifferenceInDays(startDate, endDate) { return Math.round(difference / (1000 * 3600 * 24)); } export function get12HourTimeFormat(time) { + if (!time) { + return null; + } + // Check correct time format and split into components time = time.toString().match(/^([01]\d|2[0-3])(:)([0-5]\d)?$/) || [time]; @@ -20,8 +24,12 @@ export function get12HourTimeFormat(time) { return time.join(""); // return adjusted time or original string } export function get12HourTimeMobileFormat(time) { + if (!time) { + return null; + } + // Check correct time format and split into components - time = time.toString().match(/^([01]\d|2[0-3])(:)([0-5]\d)?$/) || [time]; + time = time?.toString().match(/^([01]\d|2[0-3])(:)([0-5]\d)?$/) || [time]; if (time.length > 1) { // If time format correct diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index f7c3ddc3b..208a301e4 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -107,8 +107,12 @@ export async function getImplicitNavigation(toRoute) { */ export async function navigateToHeritageFunnel({ shouldSaveSession, pageNameToLog }) { - console.log(new Date() + " navigateToHeritageFunnel: " + JSON.stringify(applicationConfig)); - console.log(new Date() + " navigateToHeritageFunnel: " + applicationConfig.HERITAGE_FUNNEL); + const log = getQuerystringParameter(queryStrings.LOG); + if (eval(log)) { + console.log(new Date() + " applicationConfig: " + JSON.stringify(applicationConfig)); + console.log(new Date() + " navigateToHeritageFunnel: " + applicationConfig.HERITAGE_FUNNEL); + } + // Create the order (or save existing order) when navigating to Heritage Funnel. if (shouldSaveSession) { await saveSession({ pageNameToLog: pageNameToLog, shouldAwaitSaveSessionQueue: true }); diff --git a/src/layouts/confirmation/add-to-calendar/add-to-calendar.vue b/src/layouts/confirmation/add-to-calendar/add-to-calendar.vue index 4cbe0d748..a4cdcbb6f 100644 --- a/src/layouts/confirmation/add-to-calendar/add-to-calendar.vue +++ b/src/layouts/confirmation/add-to-calendar/add-to-calendar.vue @@ -34,6 +34,8 @@ import { import store from "@/store"; import { serviceType } from "@/constants/service-type"; import { applicationConfig } from "@/constants/application-config.js"; +import baseMixin from "@/mixins/base-mixin.js"; + export default { name: "add-to-calendar", components: { @@ -110,10 +112,10 @@ export default { return this.getCmsContent(this.sameDayDropOffWidgetName, "BodyText"); }, UniqueId() { - return store.getters.submittedOrder.referralNumber?.toString(); + return this.getSubmittedOrder()?.referralNumber?.toString(); }, ServiceType() { - const isRepair = store.getters.submittedOrder.damage.isRepair; + const isRepair = this.getSubmittedOrder()?.damage.isRepair; const funnelHasRecalibrationPart = store.getters.isRecalibrationOnSubmittedOrder; if (!isRepair) { if (funnelHasRecalibrationPart) { @@ -125,7 +127,7 @@ export default { return serviceType.REPAIR; }, RouteCode() { - return store.getters.submittedOrder.schedule.routeCode; + return this.getSubmittedOrder()?.schedule.routeCode; }, Appointment() { var subject = ""; @@ -206,6 +208,9 @@ export default { }, methods: { + getSubmittedOrder() { + return baseMixin.methods.getSubmittedOrder(); + }, setCalendarAppointment(calendarOption) { if ( calendarOption.name == calendarOptions.ICAL || diff --git a/src/layouts/confirmation/confirmation.spec.js b/src/layouts/confirmation/confirmation.spec.js index a079fab83..bf544c13a 100644 --- a/src/layouts/confirmation/confirmation.spec.js +++ b/src/layouts/confirmation/confirmation.spec.js @@ -19,67 +19,6 @@ beforeEach(() => { jest.restoreAllMocks(); jest.clearAllMocks(); store.getters = { - submittedOrder: { - schedule: { - date: "2023-01-01", - startTime: "09:00", - endTime: "10:00", - routeCode: "000", - jobMaxMinutes: "120", - jobMinMinutes: "60", - }, - lineItems: { - glassParts: [ - { - partNumber: "ABC123", - }, - ], - supportingItems: [], - }, - serviceLocation: { - address: "test", - address2: "123", - city: "test", - state: "AZ", - appointmentType: "Inshop", - zipCode: "12345", - zipCodeCtu: "01234", - provider: { - providerNumber: "123", - address: { - streetAddress: "test1", - city: "test", - state: "AZ", - zipCode: "12345", - zipCodeCtu: "01234", - }, - }, - }, - damage: { - isRepair: false, - }, - payment: { - isPia: true, - isInsurance: false, - insuranceCoverage: { - coverageStatus: "test", - }, - }, - policy: { - isNoComp: false, - currentDeductible: 1, - insuranceCompanyName: "test name", - }, - referralNumber: "1234567", - vehicle: { - year: "2004", - make: "Ford", - model: "F Series F250", - }, - customer: { - emailAddress: "test@test.com", - }, - }, order: { schedule: { date: "2023-01-01", @@ -96,6 +35,7 @@ beforeEach(() => { supportingItems: [], }, serviceLocation: { + appointmentType: AppointmentTypeStrings.IN_SHOP, address: "test", address2: "123", city: "test", @@ -180,6 +120,20 @@ describe("computed properties...", () => { test("ScheduleDateFormatted should return date in expected format.", () => { //Arrange const { wrapper } = setupMocks({}); + wrapper.vm.submittedOrder = { + vehicle: { + imageUrl: "" + }, + schedule: { + startTime: "09:00", + endTime: "11:00", + date: "2023-01-01", + jobMaxMinutes: 120, + jobMinMinutes: 60, + routeCode: "" + }, + serviceLocation: store.getters.order.serviceLocation + }; // Act const testValue = wrapper.vm.ScheduleDateFormatted; @@ -189,11 +143,22 @@ describe("computed properties...", () => { }); test("ScheduleTimeFormatted should return mobile time in expected format.", () => { //Arrange - store.getters.submittedOrder.serviceLocation.appointmentType = - AppointmentTypeStrings.MOBILE; - store.getters.submittedOrder.schedule.startTime = "09:00"; - store.getters.submittedOrder.schedule.endTime = "11:00"; const { wrapper } = setupMocks({}); + wrapper.vm.submittedOrder = { + vehicle: { + imageUrl: "" + }, + schedule: { + startTime: "09:00", + endTime: "11:00", + date: "2024-09-28", + jobMaxMinutes: 120, + jobMinMinutes: 60, + routeCode: "" + }, + serviceLocation: store.getters.order.serviceLocation + }; + wrapper.vm.submittedOrder.serviceLocation.appointmentType = AppointmentTypeStrings.MOBILE; // Act const testValue = wrapper.vm.ScheduleTimeFormatted; @@ -203,11 +168,22 @@ describe("computed properties...", () => { }); test("ScheduleTimeFormatted should return DROP_OFF time in expected format.", () => { //Arrange - store.getters.submittedOrder.serviceLocation.appointmentType = - AppointmentTypeStrings.DROP_OFF; - store.getters.submittedOrder.schedule.startTime = "09:00"; - store.getters.submittedOrder.schedule.endTime = "11:00"; const { wrapper } = setupMocks({}); + wrapper.vm.submittedOrder = { + vehicle: { + imageUrl: "" + }, + schedule: { + startTime: "09:00", + endTime: "11:00", + date: "2024-09-28", + jobMaxMinutes: 120, + jobMinMinutes: 60, + routeCode: "" + }, + serviceLocation: store.getters.order.serviceLocation + }; + wrapper.vm.submittedOrder.serviceLocation.appointmentType = AppointmentTypeStrings.DROP_OFF; // Act const testValue = wrapper.vm.ScheduleTimeFormatted; @@ -217,11 +193,22 @@ describe("computed properties...", () => { }); test("ScheduleTimeFormatted should return Inshop time in expected format.", () => { //Arrange - store.getters.submittedOrder.serviceLocation.appointmentType = - AppointmentTypeStrings.IN_SHOP; - store.getters.submittedOrder.schedule.startTime = "09:00"; - store.getters.submittedOrder.schedule.endTime = "11:00"; const { wrapper } = setupMocks({}); + wrapper.vm.submittedOrder = { + vehicle: { + imageUrl: "" + }, + schedule: { + startTime: "09:00", + endTime: "11:00", + date: "2024-09-28", + jobMaxMinutes: 120, + jobMinMinutes: 60, + routeCode: "" + }, + serviceLocation: store.getters.order.serviceLocation + }; + wrapper.vm.submittedOrder.serviceLocation.appointmentType = AppointmentTypeStrings.IN_SHOP; // Act const testValue = wrapper.vm.ScheduleTimeFormatted; @@ -231,10 +218,21 @@ describe("computed properties...", () => { }); test("AppointmentWordingText should return mobile text in expected format.", () => { //Arrange - store.getters.submittedOrder.serviceLocation.appointmentType = - AppointmentTypeStrings.MOBILE; - const { wrapper } = setupMocks({}); + wrapper.vm.submittedOrder = { + vehicle: { + imageUrl: "" + }, + schedule: { + endTime: "10:00", + date: "2024-09-28", + jobMaxMinutes: 120, + jobMinMinutes: 60, + routeCode: "" + }, + serviceLocation: store.getters.order.serviceLocation + }; + wrapper.vm.submittedOrder.serviceLocation.appointmentType = AppointmentTypeStrings.MOBILE; // Act const testValue = wrapper.vm.AppointmentWordingText; @@ -243,10 +241,21 @@ describe("computed properties...", () => { }); test("AppointmentWordingText should return DROP_OFF text in expected format.", () => { //Arrange - store.getters.submittedOrder.serviceLocation.appointmentType = - AppointmentTypeStrings.DROP_OFF; - const { wrapper } = setupMocks({}); + wrapper.vm.submittedOrder = { + vehicle: { + imageUrl: "" + }, + schedule: { + endTime: "10:00", + date: "2024-09-28", + jobMaxMinutes: 120, + jobMinMinutes: 60, + routeCode: "" + }, + serviceLocation: store.getters.order.serviceLocation + }; + wrapper.vm.submittedOrder.serviceLocation.appointmentType = AppointmentTypeStrings.DROP_OFF; // Act const testValue = wrapper.vm.AppointmentWordingText; @@ -256,10 +265,20 @@ describe("computed properties...", () => { }); test("AppointmentWordingText should return IN_SHOP text in expected format.", () => { //Arrange - store.getters.submittedOrder.serviceLocation.appointmentType = - AppointmentTypeStrings.IN_SHOP; - const { wrapper } = setupMocks({}); + wrapper.vm.submittedOrder = { + vehicle: { + imageUrl: "" + }, + schedule: { + endTime: "10:00", + date: "2024-09-28", + jobMaxMinutes: 120, + jobMinMinutes: 60, + routeCode: "" + }, + serviceLocation: store.getters.order.serviceLocation + }; // Act const testValue = wrapper.vm.AppointmentWordingText; @@ -280,6 +299,19 @@ describe("computed properties...", () => { test("ScheduleDate should return date in expected format.", () => { //Arrange const { wrapper } = setupMocks({}); + wrapper.vm.submittedOrder = { + vehicle: { + imageUrl: "" + }, + schedule: { + date: "2023-01-01", + endTime: "10:00", + jobMaxMinutes: 120, + jobMinMinutes: 60, + routeCode: "" + }, + serviceLocation: store.getters.order.serviceLocation + }; // Act const testValue = wrapper.vm.ScheduleDate; @@ -290,6 +322,19 @@ describe("computed properties...", () => { test("ScheduleStartTime should return time in expected format.", () => { //Arrange const { wrapper } = setupMocks({}); + wrapper.vm.submittedOrder = { + vehicle: { + imageUrl: "" + }, + schedule: { + startTime: "09:00", + date: "2024-09-28", + jobMaxMinutes: 120, + jobMinMinutes: 60, + routeCode: "" + }, + serviceLocation: store.getters.order.serviceLocation + }; // Act const testValue = wrapper.vm.ScheduleStartTime; @@ -300,6 +345,19 @@ describe("computed properties...", () => { test("ScheduleEndTime should return time in expected format.", () => { //Arrange const { wrapper } = setupMocks({}); + wrapper.vm.submittedOrder = { + vehicle: { + imageUrl: "" + }, + schedule: { + endTime: "10:00", + date: "2024-09-28", + jobMaxMinutes: 120, + jobMinMinutes: 60, + routeCode: "" + }, + serviceLocation: store.getters.order.serviceLocation + }; // Act const testValue = wrapper.vm.ScheduleEndTime; @@ -344,6 +402,18 @@ describe("computed properties...", () => { //Arrange const { wrapper } = setupMocks({}); + wrapper.vm.submittedOrder = { + vehicle: { + imageUrl: "" + }, + schedule: { + date: "2024-09-28", + jobMaxMinutes: 120, + jobMinMinutes: 60, + routeCode: "" + }, + serviceLocation: store.getters.order.serviceLocation + }; // Act const testValue = wrapper.vm.ServiceLocationFullAddress; @@ -355,6 +425,18 @@ describe("computed properties...", () => { //Arrange const { wrapper } = setupMocks({}); + wrapper.vm.submittedOrder = { + vehicle: { + imageUrl: "" + }, + schedule: { + date: "2024-09-28", + jobMaxMinutes: 120, + jobMinMinutes: 60, + routeCode: "" + }, + serviceLocation: store.getters.order.serviceLocation + }; // Act const testValue = wrapper.vm.ProviderFullAddress; @@ -366,6 +448,17 @@ describe("computed properties...", () => { //Arrange const { wrapper } = setupMocks({}); + wrapper.vm.submittedOrder = { + vehicle: { + imageUrl: "" + }, + schedule: { + date: "2024-09-28", + jobMaxMinutes: 120, + jobMinMinutes: 60, + routeCode: "" + } + }; // Act const testValue = wrapper.vm.AppointmentDuration; @@ -375,9 +468,18 @@ describe("computed properties...", () => { }); test("Appointment Duration should return with correct duration values in expected format for hours.", () => { //Arrange - store.getters.submittedOrder.schedule.jobMaxMinutes = 120; - store.getters.submittedOrder.schedule.jobMinMinutes = 60; const { wrapper } = setupMocks({}); + wrapper.vm.submittedOrder = { + vehicle: { + imageUrl: "" + }, + schedule: { + date: "2024-09-28", + jobMaxMinutes: 120, + jobMinMinutes: 60, + routeCode: "" + } + }; // Act const testValue = wrapper.vm.AppointmentDuration; @@ -387,9 +489,18 @@ describe("computed properties...", () => { }); test("Appointment Duration should return with correct duration values in expected format for minutes.", () => { //Arrange - store.getters.submittedOrder.schedule.jobMaxMinutes = 45; - store.getters.submittedOrder.schedule.jobMinMinutes = 30; const { wrapper } = setupMocks({}); + wrapper.vm.submittedOrder = { + vehicle: { + imageUrl: "" + }, + schedule: { + date: "2024-09-28", + jobMaxMinutes: 45, + jobMinMinutes: 30, + routeCode: "" + } + }; // Act const testValue = wrapper.vm.AppointmentDuration; @@ -400,10 +511,18 @@ describe("computed properties...", () => { test("Appointment Duration should return with All Day.", () => { //Arrange - store.getters.submittedOrder.schedule.jobMaxMinutes = 45; - store.getters.submittedOrder.schedule.jobMinMinutes = 30; - store.getters.submittedOrder.schedule.routeCode = RouteCodeFlags.ALL_DAY_DROP_OFF; const { wrapper } = setupMocks({}); + wrapper.vm.submittedOrder = { + vehicle: { + imageUrl: "" + }, + schedule: { + date: "2024-09-28", + jobMaxMinutes: 45, + jobMinMinutes: 30, + routeCode: RouteCodeFlags.ALL_DAY_DROP_OFF + } + }; // Act const testValue = wrapper.vm.AppointmentDuration; @@ -414,10 +533,18 @@ describe("computed properties...", () => { test("Appointment Duration should return with Overnight.", () => { //Arrange - store.getters.submittedOrder.schedule.jobMaxMinutes = 45; - store.getters.submittedOrder.schedule.jobMinMinutes = 30; - store.getters.submittedOrder.schedule.routeCode = RouteCodeFlags.OVERNIGHT_DROP_OFF; const { wrapper } = setupMocks({}); + wrapper.vm.submittedOrder = { + vehicle: { + imageUrl: "" + }, + schedule: { + date: "2024-09-28", + jobMaxMinutes: 45, + jobMinMinutes: 30, + routeCode: RouteCodeFlags.OVERNIGHT_DROP_OFF + } + }; // Act const testValue = wrapper.vm.AppointmentDuration; @@ -443,4 +570,4 @@ function setupMocks({ customMountOptions }) { ]; const wrapper = shallowMount(confirmation, mountOptions); return { wrapper }; -} +} \ No newline at end of file diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index b46154756..19e4d2caf 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -109,16 +109,19 @@ import { getDisplayTextForDurationLength } from "@/helpers/duration-length-helpe export default { name: "confirmation", async beforeRouteEnter(to, from, next) { + console.log("beforeRoute.."); await baseMixin.methods.dispatchStoreAction(storeActions.CREATE_SUBMITTED_ORDER); // Call APIs const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage); + const submittedOrder = baseMixin.methods.getSubmittedOrder(); + const wipersPromise = baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_WIPERS, { - serviceZipCode: store.getters.submittedOrder.serviceLocation.zipCode, - carId: store.getters.submittedOrder.vehicle.carId, + serviceZipCode: submittedOrder.serviceLocation.zipCode, + carId: submittedOrder.vehicle.carId, }, "confirmation" ); @@ -147,24 +150,26 @@ export default { const resultMap = await settleAllPromises(promiseResultMap); const availableVaps = [resultMap.rainDefense, ...resultMap.wipers]; - const lineItemsFromSubmittedOrder = deepClone(store.getters.submittedOrder.lineItems); + const lineItemsFromSubmittedOrder = deepClone(submittedOrder.lineItems); // Call the "next" function to complete the transition to this page. next((vm) => { vm.setCmsContent(resultMap.cmsContent); vm.lineItems = lineItemsFromSubmittedOrder; vm.vaps = availableVaps; + vm.submittedOrder = submittedOrder; }); }, data() { return { lineItems: [], vaps: [], + submittedOrder: null, }; }, computed: { ShowCart() { - if (this.isPia && store.getters.submittedOrder.settledTenderAmount == 0) { + if (this.isPia && this.submittedOrder?.settledTenderAmount == 0) { // settleTenderAmount always shows 0 via localhost or dev. // Temporarily set return true to see cart in localhost or dev environment return false; @@ -179,7 +184,7 @@ export default { return this.getCmsContent("ScheduleConfirmationWidget", "Image"); }, CustomerPortalLoginToken() { - return store.getters.submittedOrder.customerPortalLoginToken; + return this.submittedOrder?.customerPortalLoginToken; }, ConfirmationEmailText() { return this.getCmsContent("ConfirmationEmailWidget", "BodyText") @@ -189,16 +194,16 @@ export default { ?.replaceAll(">", ">"); }, ScheduleDate() { - return store.getters.submittedOrder.schedule.date; + return this.submittedOrder?.schedule?.date; }, AppointmentType() { - return store.getters.submittedOrder.serviceLocation.appointmentType; + return this.submittedOrder?.serviceLocation?.appointmentType; }, ScheduleStartTime() { - return store.getters.submittedOrder.schedule.startTime; + return this.submittedOrder?.schedule?.startTime; }, ScheduleEndTime() { - return store.getters.submittedOrder.schedule.endTime; + return this.submittedOrder?.schedule?.endTime; }, InShopWordingText() { return this.getCmsContent("InShopWordingWidget", "BodyText"); @@ -210,31 +215,31 @@ export default { return this.getCmsContent("DropOffWordingWidget", "BodyText"); }, ServiceLocationAddress() { - return store.getters.submittedOrder.serviceLocation.address; + return this.submittedOrder?.serviceLocation?.address; }, ServiceLocationAddress2() { - return store.getters.submittedOrder.serviceLocation.address2; + return this.submittedOrder?.serviceLocation?.address2; }, ServiceLocationCity() { - return store.getters.submittedOrder.serviceLocation.city; + return this.submittedOrder?.serviceLocation?.city; }, ServiceLocationState() { - return store.getters.submittedOrder.serviceLocation.state; + return this.submittedOrder?.serviceLocation?.state; }, ServiceLocationZipCode() { - return store.getters.submittedOrder.serviceLocation.zipCode; + return this.submittedOrder?.serviceLocation?.zipCode; }, ProviderAddress() { - return store.getters.submittedOrder.serviceLocation.provider.address.streetAddress; + return this.submittedOrder?.serviceLocation?.provider?.address?.streetAddress; }, ProviderCity() { - return store.getters.submittedOrder.serviceLocation.provider.address.city; + return this.submittedOrder?.serviceLocation?.provider?.address?.city; }, ProviderState() { - return store.getters.submittedOrder.serviceLocation.provider.address.state; + return this.submittedOrder?.serviceLocation?.provider?.address?.state; }, ProviderZipCode() { - return store.getters.submittedOrder.serviceLocation.provider.address.zipCode; + return this.submittedOrder?.serviceLocation?.provider?.address?.zipCode; }, AppointmentWordingText() { if (this.AppointmentType == AppointmentTypeStrings.MOBILE) { @@ -268,7 +273,7 @@ export default { // This conversion ensures we don't get get GMT induced date changes const dateObject = convertDateStringToDate(this.ScheduleDate); // Ex: Tuesday, April 22 - return dateObject.toLocaleDateString("en-us", { + return dateObject?.toLocaleDateString("en-us", { weekday: "long", month: "long", day: "numeric", @@ -286,19 +291,19 @@ export default { } }, vehicleBannerImageUrl() { - return store.getters.submittedOrder?.vehicle.imageUrl; + return this.submittedOrder?.vehicle.imageUrl; }, damageInfo() { - return store.getters.submittedOrder.damage; + return this.submittedOrder?.damage; }, isInsurance() { - return store.getters.submittedOrder.payment.isInsurance; + return this.submittedOrder?.payment?.isInsurance; }, isNoComp() { - return store.getters.submittedOrder.policy.isNoComp; + return this.submittedOrder?.policy?.isNoComp; }, isItac() { - return store.getters.submittedOrder.policy.isItac; + return this.submittedOrder?.policy?.isItac; }, hasVapsInCart() { if (this.lineItems?.vaps?.length > 0) { @@ -311,32 +316,28 @@ export default { if (this.isNoComp || this.isItac) { return coverageStatus.NOCOMP; } else { - return store.getters.submittedOrder.payment.insuranceCoverage.coverageStatus; + return this.submittedOrder?.payment?.insuranceCoverage?.coverageStatus; } }, currentDeductible() { - return store.getters.submittedOrder.policy.currentDeductible; + return this.submittedOrder?.policy?.currentDeductible; }, insuranceCompanyName() { - return store.getters.submittedOrder.policy.insuranceCompanyName; + return this.submittedOrder?.policy?.insuranceCompanyName; }, isPia() { - return store.getters.submittedOrder?.payment.isPia; + return this.submittedOrder?.payment?.isPia; }, AppointmentDuration() { - const durationMaximum = store.getters.submittedOrder?.schedule?.jobMaxMinutes; - const durationMinimum = store.getters.submittedOrder?.schedule?.jobMinMinutes; + const durationMaximum = this.submittedOrder?.schedule?.jobMaxMinutes; + const durationMinimum = this.submittedOrder?.schedule?.jobMinMinutes; const durationLengthString = "Duration: "; if ( - store.getters.submittedOrder?.schedule?.routeCode.includes( - RouteCodeFlags.ALL_DAY_DROP_OFF - ) + this.submittedOrder?.schedule?.routeCode.includes(RouteCodeFlags.ALL_DAY_DROP_OFF) ) { return durationLengthString.concat("All Day"); } else if ( - store.getters.submittedOrder?.schedule?.routeCode.includes( - RouteCodeFlags.OVERNIGHT_DROP_OFF - ) + this.submittedOrder?.schedule?.routeCode.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF) ) { return durationLengthString.concat("Overnight"); } else { @@ -348,7 +349,7 @@ export default { }, methods: { arePagePrerequisitesValid() { - if (store.getters.hasSubmittedOrder) { + if (baseMixin.methods.hasSubmittedOrder()) { return true; } diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index 8723ab85a..aaa588d7e 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -572,7 +572,10 @@ export default { ); }, hasSubmittedOrder() { - return this.$store.getters.hasSubmittedOrder; + return baseMixin.methods.hasSubmittedOrder(); + }, + getSubmittedOrder() { + return baseMixin.methods.getSubmittedOrder(); }, openModal(modalName) { this.$refs[modalName].openModal(); @@ -597,17 +600,17 @@ export default { }, isInsurance() { return this.hasSubmittedOrder() - ? this.$store.getters.submittedOrder.payment.isInsurance + ? this.getSubmittedOrder()?.payment.isInsurance : this.$store.getters.payment.isInsurance; }, isNoComp() { return this.hasSubmittedOrder() - ? this.$store.getters.submittedOrder.policy.isNoComp + ? this.getSubmittedOrder()?.policy.isNoComp : this.$store.getters.policy.isNoComp; }, isItac() { return this.hasSubmittedOrder() - ? this.$store.getters.submittedOrder.policy.isItac + ? this.getSubmittedOrder()?.policy.isItac : this.$store.getters.policy.isItac; }, hasVapsInCart() { @@ -622,13 +625,13 @@ export default { return coverageStatus.NOCOMP; } else { return this.hasSubmittedOrder() - ? this.$store.getters.submittedOrder.payment.insuranceCoverage.coverageStatus + ? this.getSubmittedOrder()?.payment.insuranceCoverage.coverageStatus : this.$store.getters.payment.insuranceCoverage.coverageStatus; } }, currentDeductible() { return this.hasSubmittedOrder() - ? this.$store.getters.submittedOrder.policy.currentDeductible + ? this.getSubmittedOrder()?.policy.currentDeductible : this.$store.getters.policy.currentDeductible; }, insuranceCompanyName() { diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 9ce6874ae..416113d2e 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -37,9 +37,11 @@ export default { const currentPageName = getPageNameByQueryString(); await this.validateSession(); + const submittedOrder = baseMixin.methods.getSubmittedOrder(); + const refSequenceNum = store.getters.order.referralSequenceNumber || - store.getters.submittedOrder?.referralSequenceNumber; + submittedOrder?.referralSequenceNumber; var payload = { userId: getUserIdValue(), @@ -125,8 +127,9 @@ export default { const isDefined = (x) => x !== null && x !== undefined; // Get correct order object - const hasSubmittedOrder = store.getters.hasSubmittedOrder; - const order = hasSubmittedOrder ? store.getters.submittedOrder : store.getters.order; + const hasSubmittedOrder = baseMixin.methods.hasSubmittedOrder(); + const submittedOrder = baseMixin.methods.getSubmittedOrder(); + const order = hasSubmittedOrder ? submittedOrder : store.getters.order; // Begin assembling payload for data layer const payload = {}; diff --git a/src/mixins/analytics-mixin.spec.js b/src/mixins/analytics-mixin.spec.js index e56840c61..87d85e952 100644 --- a/src/mixins/analytics-mixin.spec.js +++ b/src/mixins/analytics-mixin.spec.js @@ -21,6 +21,7 @@ import { getSessionKeyValue, getUserIdValue, } from "@/helpers/heritage-integration/cookie-helper"; +import baseMixin from "./base-mixin"; const parts = { windshield: { @@ -470,8 +471,9 @@ describe("analyticsMixin.js", () => { test("Pushes correct data when submitted order is present", () => { // Arrange window.dataLayer = []; - store.getters.hasSubmittedOrder = true; - store.getters.submittedOrder = store.getters.order; + baseMixin.methods.hasSubmittedOrder = jest.fn().mockReturnValue(true); + baseMixin.methods.getSubmittedOrder = jest.fn().mockReturnValue(store.getters.order); + store.getters.order = { vehicle: { year: null, diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index c86cdacb5..571ac3638 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -166,9 +166,7 @@ export default { ); } - const order = store.getters.hasSubmittedOrder - ? store.getters.submittedOrder - : store.getters.order; + const order = this.hasSubmittedOrder() ? this.getSubmittedOrder() : store.getters.order; if ( order.payment.insuranceCoverage.isVerified && @@ -224,6 +222,12 @@ export default { return [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)]; } }, + getSubmittedOrder() { + return JSON.parse(window.sessionStorage.getItem("submittedOrder")); + }, + hasSubmittedOrder() { + return window.sessionStorage.getItem("submittedOrder") !== null; + }, }, computed: { storeActions() { diff --git a/src/mixins/base-mixin.spec.js b/src/mixins/base-mixin.spec.js index 77295b33f..9a062a831 100644 --- a/src/mixins/base-mixin.spec.js +++ b/src/mixins/base-mixin.spec.js @@ -226,15 +226,16 @@ describe("baseMixin.js", () => { const payment = { insuranceCoverage: { isVerified: true } }; const policy = { isNoComp: false, isItac: false, currentDeductible: 250 }; + mixIn.methods.hasSubmittedOrder = jest.fn().mockReturnValue(true); + mixIn.methods.getSubmittedOrder = jest.fn().mockReturnValue({ + payment: payment, + policy: policy, + }); + store.getters = { payment: {}, policy: {}, order: {}, - submittedOrder: { - payment: payment, - policy: policy, - }, - hasSubmittedOrder: true, }; var amtDue = mixIn.methods.getAmountDue(lineItems); @@ -301,6 +302,8 @@ describe("baseMixin.js", () => { const payment = { isInsurance: null, insuranceCoverage: { isVerified: null } }; const policy = { isNoComp: false, isItac: false, currentDeductible: 0 }; + mixIn.methods.hasSubmittedOrder = jest.fn().mockReturnValue(false); + store.getters = { payment: payment, policy: policy, diff --git a/src/router/index.js b/src/router/index.js index 23b61282c..23751e43d 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -64,7 +64,7 @@ const routes = [ } // Intercept all navigation if a submitted order exists in storage - if (store.getters.hasSubmittedOrder) { + if (window.sessionStorage.getItem("submittedOrder") !== null) { if (to.query.fmgPage !== funnelStartPageName) { to.query.fmgPage = fmgPageValues.CONFIRMATION; } @@ -409,6 +409,7 @@ async function navigate( const zip = getQuerystringParameter(queryStrings.ZIP_CODE); const promo = getQuerystringParameter(queryStrings.PROMO); const pageError = getQuerystringParameter(queryStrings.PAGE_ERROR); + const log = getQuerystringParameter(queryStrings.LOG); if ( hasZip && @@ -428,6 +429,10 @@ async function navigate( queryStringsObject[queryStrings.PAGE_ERROR] = pageError; } + if (log) { + queryStringsObject[queryStrings.LOG] = log; + } + router.push({ name: "root", query: Object.assign(optionalQuery, queryStringsObject), diff --git a/src/store/index.js b/src/store/index.js index aa5747a0f..cf29f5faf 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -883,8 +883,6 @@ export const getters = { .filter((x) => !!x.isActive) .map((x) => x.settings) .reduce((r, c) => Object.assign(r, c), {}) ?? {}, - submittedOrder: (state) => JSON.parse(window.sessionStorage.getItem("submittedOrder")), - hasSubmittedOrder: (state) => window.sessionStorage.getItem("submittedOrder") !== null, isVerifiedAndDeductibleZeroConfirmed: (state) => { // used as a CMS variable on /payment-method, needed for FunnelSubHeaderWidget on cart pages if ( @@ -2798,7 +2796,7 @@ export const actions = { }, createSubmittedOrder(context) { - if (context.getters.hasSubmittedOrder) { + if (window.sessionStorage.getItem("submittedOrder") !== null) { return; }