From fa036d7b114c7df3df77faa25e198a400f2ce72d Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Fri, 16 Jan 2026 11:06:06 -0500 Subject: [PATCH 01/11] CASH-2112 add text block --- src/layouts/payment-adyen/payment-adyen.vue | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/layouts/payment-adyen/payment-adyen.vue b/src/layouts/payment-adyen/payment-adyen.vue index 42b7d03fb..4427cf92c 100644 --- a/src/layouts/payment-adyen/payment-adyen.vue +++ b/src/layouts/payment-adyen/payment-adyen.vue @@ -36,6 +36,10 @@ :isItac="isItac" :isNoComp="isNoComp" :isCollapsible="false" /> + @@ -56,6 +60,7 @@ import funnelHeader from "@/fmg-components/funnel-header/funnel-header"; import navbar from "@/fmg-components/nav-bar/nav-bar"; import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header"; import alert from "@/ux-components/alert/alert"; +import textBlock from "@/digital-components/text-block/text-block"; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { settleAllPromises } from "@/helpers/layout-helper"; @@ -645,6 +650,7 @@ export default { navbar, cart, alert, + textBlock, }, }; @@ -671,5 +677,10 @@ export default { margin: 0 0.5rem; } } + + .payment-disclaimer p { + font-size: 0.875rem; + line-height: 1.2; + } } From f04c3c607cb7b91be1f491f18e2f9e451a5abcee Mon Sep 17 00:00:00 2001 From: Chris Redelinghuys Date: Thu, 15 Jan 2026 14:45:42 -0500 Subject: [PATCH 02/11] CASH-2180: Remove QPD parts for insurance orders --- .../insurance-company/insurance-company.vue | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/layouts/insurance-company/insurance-company.vue b/src/layouts/insurance-company/insurance-company.vue index 21c62078a..0ec8fd5e9 100644 --- a/src/layouts/insurance-company/insurance-company.vue +++ b/src/layouts/insurance-company/insurance-company.vue @@ -59,6 +59,7 @@ import store from "@/store"; import { flushSaveSessionQueue } from "@/helpers/heritage-integration/order-helper"; import { errorMessages } from "@/constants/error-messages"; import { required, regex } from "@/helpers/validation-rules"; +import { partTypeStrings } from "@/constants/part-type-strings"; defineRule("insurance-company-required", required(errorMessages.INSURANCE_COMPANY_REQUIRED)); @@ -164,6 +165,8 @@ export default { // await any pending save-sessions. if you don't, we will save the new parent account into vuex and then a pending async save-session response overwrites it await flushSaveSessionQueue(); + this.removeQPDLineItemIfExists(); + await this.dispatchStoreAction( this.storeActions.SAVE_PARENT_ACCOUNT_NUMBER, this.parentAccountNumber.toString(), @@ -193,6 +196,20 @@ export default { handlePageShow() { window.location.reload(); }, + removeQPDLineItemIfExists() { + const lineItems = deepClone(store.getters.order.lineItems); + const removeQPDpartIndex = lineItems?.supportingItems.findIndex( + (item) => item.partType == partTypeStrings.QUOTE_PAGE_DISCOUNT + ); + if (removeQPDpartIndex >= 0) { + lineItems.supportingItems.splice(removeQPDpartIndex, 1); + baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING, + lineItems.supportingItems, + false + ); + } + }, }, unmounted() { window.removeEventListener("pageshow", this.handlePageShow); From 35cb35100e259a2f4abc7683950f6631aa016902 Mon Sep 17 00:00:00 2001 From: Chris Redelinghuys Date: Thu, 15 Jan 2026 15:35:59 -0500 Subject: [PATCH 03/11] CASH-2180: Filter out QPD parts --- .../insurance-company/insurance-company.vue | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/layouts/insurance-company/insurance-company.vue b/src/layouts/insurance-company/insurance-company.vue index 0ec8fd5e9..4da99fec9 100644 --- a/src/layouts/insurance-company/insurance-company.vue +++ b/src/layouts/insurance-company/insurance-company.vue @@ -59,7 +59,6 @@ import store from "@/store"; import { flushSaveSessionQueue } from "@/helpers/heritage-integration/order-helper"; import { errorMessages } from "@/constants/error-messages"; import { required, regex } from "@/helpers/validation-rules"; -import { partTypeStrings } from "@/constants/part-type-strings"; defineRule("insurance-company-required", required(errorMessages.INSURANCE_COMPANY_REQUIRED)); @@ -198,17 +197,14 @@ export default { }, removeQPDLineItemIfExists() { const lineItems = deepClone(store.getters.order.lineItems); - const removeQPDpartIndex = lineItems?.supportingItems.findIndex( - (item) => item.partType == partTypeStrings.QUOTE_PAGE_DISCOUNT + lineItems.supportingItems = baseMixin.methods.filterOutQuotePageDiscountPart( + lineItems.supportingItems + ); + baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING, + lineItems.supportingItems, + false ); - if (removeQPDpartIndex >= 0) { - lineItems.supportingItems.splice(removeQPDpartIndex, 1); - baseMixin.methods.dispatchStoreAction( - storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING, - lineItems.supportingItems, - false - ); - } }, }, unmounted() { From 570b70465959d69dd0b099b1dd764ab58343e269 Mon Sep 17 00:00:00 2001 From: Chris Redelinghuys Date: Thu, 15 Jan 2026 15:52:08 -0500 Subject: [PATCH 04/11] CASH-2180: Make asynchronous --- src/layouts/insurance-company/insurance-company.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/layouts/insurance-company/insurance-company.vue b/src/layouts/insurance-company/insurance-company.vue index 4da99fec9..1455847bd 100644 --- a/src/layouts/insurance-company/insurance-company.vue +++ b/src/layouts/insurance-company/insurance-company.vue @@ -164,7 +164,7 @@ export default { // await any pending save-sessions. if you don't, we will save the new parent account into vuex and then a pending async save-session response overwrites it await flushSaveSessionQueue(); - this.removeQPDLineItemIfExists(); + await this.removeQPDLineItemIfExists(); await this.dispatchStoreAction( this.storeActions.SAVE_PARENT_ACCOUNT_NUMBER, @@ -195,12 +195,12 @@ export default { handlePageShow() { window.location.reload(); }, - removeQPDLineItemIfExists() { + async removeQPDLineItemIfExists() { const lineItems = deepClone(store.getters.order.lineItems); lineItems.supportingItems = baseMixin.methods.filterOutQuotePageDiscountPart( lineItems.supportingItems ); - baseMixin.methods.dispatchStoreAction( + await baseMixin.methods.dispatchStoreAction( storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING, lineItems.supportingItems, false From 18efcadfc482e2add7bc63068d5df6d45e98a9fd Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Fri, 16 Jan 2026 14:01:27 -0500 Subject: [PATCH 05/11] prettier --- src/layouts/payment-adyen/payment-adyen.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/payment-adyen/payment-adyen.vue b/src/layouts/payment-adyen/payment-adyen.vue index 4427cf92c..9d5f21785 100644 --- a/src/layouts/payment-adyen/payment-adyen.vue +++ b/src/layouts/payment-adyen/payment-adyen.vue @@ -38,7 +38,7 @@ :isCollapsible="false" /> From e639edd15c4999e39531bd6dd1f93c5a56130b27 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Mon, 19 Jan 2026 06:28:15 -0500 Subject: [PATCH 06/11] CASH-2149 CASH-2149 recal ack modal for scheduling --- src/constants/analytics.js | 2 + src/constants/schedule-constants.js | 3 + src/constants/store-actions.js | 1 + src/constants/store-mutations.js | 1 + src/helpers/recal-helper.js | 8 + .../recal-ack-modal/recal-ack-modal.vue | 223 ++++++++++++++++++ src/layouts/schedule/schedule.vue | 57 ++++- src/store/index.js | 11 + src/styles/ux-variables.scss | 2 + 9 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 src/layouts/schedule/recal-ack-modal/recal-ack-modal.vue diff --git a/src/constants/analytics.js b/src/constants/analytics.js index 00088baa7..e156de11b 100644 --- a/src/constants/analytics.js +++ b/src/constants/analytics.js @@ -15,6 +15,7 @@ const GaCategories = { APPOINTMENT: "Appointment", SERVICE_LOCATION: "service-location", CONFIRMATION_CLICKED: "confirmation clicked", + RECAL_DISCLAIMER: "Recalibration disclaimer", }; const GaActions = { @@ -29,6 +30,7 @@ const GaActions = { MORE_LOCATIONS_CLICKED: "more_locations_clicked", YES: "yes", NO: "no", + ACKNOWLEDGED: "Acknowledged", }; const GaLabels = { diff --git a/src/constants/schedule-constants.js b/src/constants/schedule-constants.js index 2b626df18..2b6171075 100644 --- a/src/constants/schedule-constants.js +++ b/src/constants/schedule-constants.js @@ -11,6 +11,8 @@ const PREMIUM_FEE_PART_TYPE = "EARLY BIRD"; const PRICING_BY_DAY_PART_TYPE = "PREMAPPT GEN"; +const RECAL_ACK_YES = "Yes"; + const RouteCodeFlags = { ALL_DAY_DROP_OFF: "ALL DAY DROP OFF", OVERNIGHT_DROP_OFF: "OVERNIGHT DROP OFF", @@ -31,4 +33,5 @@ export { PRICING_BY_DAY_PART_TYPE, RouteCodeFlags, cmsWidgetFieldMappings, + RECAL_ACK_YES, }; diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index 2fc0c88eb..3afd4df24 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -111,6 +111,7 @@ const storeActions = { SAVE_PAYPAL_TOKEN: "savePaypalToken", SAVE_NEXTGEN_SETTLED_AMOUNT: "saveNextGenSettledAmount", SAVE_IS_RECAL_ACK_OPT_IN: "saveIsRecalAckOptIn", + SAVE_IS_RECAL_ACKNOWLEDGED_FOR_SCHEDULING: "saveIsRecalAcknowledgedForScheduling", SAVE_IS_OEM_GLASS_SELECTED: "saveIsOemGlassSelected", SAVE_IS_MSR_FEE_APPLICABLE: "saveIsMSRFeeApplicable", diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 5167581e0..700f527c2 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -69,6 +69,7 @@ const storeMutations = { LOCK_TOKEN: "updateLockToken", UPDATE_SETTLED_TENDER_AMOUNT: "updateSettledTenderAmount", UPDATE_IS_RECAL_ACK_OPT_IN: "updateIsRecalAckOptIn", + UPDATE_IS_RECAL_ACKNOWLEDGED_FOR_SCHEDULING: "updateIsRecalAcknowledgedForScheduling", UPDATE_IS_OEM_GLASS_SELECTED: "updateIsOemGlassSelected", UPDATE_IS_MSR_FEE_APPLICABLE: "updateIsMSRFeeApplicable", UPDATE_CASH_PRICE_SUBTOTAL: "updateCashPriceSubTotal", diff --git a/src/helpers/recal-helper.js b/src/helpers/recal-helper.js index 2794bbcf6..2a3281185 100644 --- a/src/helpers/recal-helper.js +++ b/src/helpers/recal-helper.js @@ -3,6 +3,14 @@ import { partTypeStrings } from "@/constants/part-type-strings"; const recalPartTypes = [partTypeStrings.RECALIBRATION, partTypeStrings.ADAS_RECALIBRATION]; +export function anyPartWithRequiresRecalFlag(lineItems) { + if (!lineItems) { + return false; + } + + return lineItems.glassParts?.some((li) => li.requiresRecalibration === true); +} + export function isRecalPartOrHasChildRecalPart(lineItem) { if (lineItem.childParts && lineItem.childParts.length > 0) { return isRecalPart(lineItem) || containsRecalParts(lineItem.childParts); diff --git a/src/layouts/schedule/recal-ack-modal/recal-ack-modal.vue b/src/layouts/schedule/recal-ack-modal/recal-ack-modal.vue new file mode 100644 index 000000000..e1c823cfe --- /dev/null +++ b/src/layouts/schedule/recal-ack-modal/recal-ack-modal.vue @@ -0,0 +1,223 @@ +// This modal is used to acknowledge the recal disclaimer during scheduling. // It will trigger when +there is a glass part with requiresRecalibration = true // but there is no recalibration part in +lineItems. This mostly occurs when // a zip code that does mobile only is selected but the vehicle +requires // recalibration. + + + + diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue index 1ebf47c7e..a812ab5f6 100644 --- a/src/layouts/schedule/schedule.vue +++ b/src/layouts/schedule/schedule.vue @@ -6,6 +6,12 @@ modalWidgetName="MobileFirstModalWidget" ref="mobileFirstModal" @confirm-appointment="updateTimeSlotandNavigateForward" /> +
@@ -190,6 +196,7 @@ import shopLocation from "@/layouts/schedule/shop-location/shop-location"; import timeSlotQuestion from "@/layouts/schedule/time-slot-question/time-slot-question.vue"; import durationTextBlock from "@/layouts/schedule/duration-text-block/duration-text-block.vue"; import mobileFirstModal from "@/layouts/schedule/mobile-first-modal/mobile-first-modal.vue"; +import recalAckModal from "@/layouts/schedule/recal-ack-modal/recal-ack-modal.vue"; import shopQuestion from "@/layouts/service-location/shop-question/shop-question"; import shopQuestionPopup from "@/layouts/service-location/shop-question/shop-question-popup"; @@ -216,6 +223,7 @@ import { RouteCodeFlags, PREMIUM_FEE_PART_TYPE, PRICING_BY_DAY_PART_TYPE, + RECAL_ACK_YES, } from "@/constants/schedule-constants"; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; @@ -242,6 +250,7 @@ import { isDropOffRouteCode, getTodayDate, } from "@/layouts/schedule/helpers/schedule-helper"; +import { containsRecalParts, anyPartWithRequiresRecalFlag } from "@/helpers/recal-helper"; import { DAYS_OF_WEEK } from "@/digital-components/date-picker/mixins/constants"; import { required } from "@/helpers/validation-rules"; @@ -430,6 +439,7 @@ export default { name: "schedule", data() { return { + isRecalAcknowledgedForScheduling: this.getIsRecalAcknowledgedForSchedulingFromStore(), selectedDate: this.getSelectedDateFromStore(), selectedTimeSlotInfo: this.getSelectedTimeSlotInfo(), mobilePremiumAppointmentFee: null, @@ -1252,6 +1262,9 @@ export default { this.isShowMobileFirstAppt && this.hideLoadingModal(); }, + getIsRecalAcknowledgedForSchedulingFromStore() { + return store.getters.order.isRecalAcknowledgedForScheduling; + }, getScheduleApiResponse, getServiceZipCtuCodeFromStore() { return store.getters.order.serviceLocation.zipCodeCtu; @@ -1370,7 +1383,25 @@ export default { hideLoadingModal() { this.$refs.loadingModal.hideModal(); }, + async closeRecalAcknowledgementPopup() { + this.showRecalAcknowledgementPopup = false; + }, async forwardButtonAction() { + const showRecalAcknowledgementModal = await this.showRecalAcknowledgementModal(); + if ( + showRecalAcknowledgementModal && + this.isRecalAcknowledgedForScheduling !== RECAL_ACK_YES + ) { + this.showRecalAcknowledgementPopup = true; + return; + } + + this.dispatchStoreAction( + storeActions.SAVE_IS_RECAL_ACKNOWLEDGED_FOR_SCHEDULING, + this.isRecalAcknowledgedForScheduling, + false + ); + this.navigatingForward = true; var ctu = this.zipCodeCtu; if (this.appointmentType === AppointmentTypeStrings.MOBILE) { @@ -1772,6 +1803,26 @@ export default { setSelectedDateToFirstAvailable() { this.selectedDate = this.getFirstAvailableDate(); }, + async showRecalAcknowledgementModal() { + const order = this.$store.getters.order; + const containsRecalPart = containsRecalParts(order.lineItems); + const hasPartWithRecalRequirement = anyPartWithRequiresRecalFlag(order.lineItems); + + // if any of the glass parts contain an item with the requiresRecalibration flag set to true + // and the order does not contain a recalibration part, show the recalibration acknowledgement modal + if ( + !containsRecalPart && + hasPartWithRecalRequirement && + this.isRecalAcknowledgedForScheduling !== RECAL_ACK_YES + ) { + this.$refs.navbar.removeLoader(); + this.$refs.recalAckModal.openModal(); + return true; + } + + this.closeRecalAcknowledgementPopup(); + return false; + }, async showMobileFirstModal() { if (!this.selectedRouteCodeData?.routeCode) { const pmMobileDays = experimentMixin.methods.getSettingValue( @@ -1895,6 +1946,10 @@ export default { this.updateTimeSlot(timeSlotObj); this.forwardButtonAction(); }, + updateRecalAcknowledgedAndNavigateForward(isAcknowledged) { + this.isRecalAcknowledgedForScheduling = isAcknowledged; + this.forwardButtonAction(); + }, }, watch: { appointmentTypeFromAppointmentTypeQuestion: { @@ -1940,7 +1995,7 @@ export default { textBlock, timeSlotQuestion, mobileFirstModal, - + recalAckModal, alert, serviceZipModalQuestion, appointmentTypeQuestion, diff --git a/src/store/index.js b/src/store/index.js index 8faf39f73..e9b379b56 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -190,6 +190,7 @@ const getDefaultState = () => { lockToken: null, settledTenderAmount: 0, isRecalAckOptIn: false, + isRecalAcknowledgedForScheduling: "", isMSRFeeApplicable: false, }, applicationUser: { @@ -343,6 +344,9 @@ export const mutations = { updateIsRecalAckOptIn(state, isRecalAckOptIn) { state.order.isRecalAckOptIn = isRecalAckOptIn; }, + updateIsRecalAcknowledgedForScheduling(state, isRecalAcknowledgedForScheduling) { + state.order.isRecalAcknowledgedForScheduling = isRecalAcknowledgedForScheduling; + }, updateIsOemGlassSelected(state, isOemGlassSelected) { state.order.damage.installOemGlass = isOemGlassSelected; }, @@ -2965,6 +2969,13 @@ export const actions = { context.commit(storeMutations.UPDATE_IS_RECAL_ACK_OPT_IN, isRecalAckOptIn); }, + saveIsRecalAcknowledgedForScheduling(context, isRecalAcknowledgedForScheduling) { + context.commit( + storeMutations.UPDATE_IS_RECAL_ACKNOWLEDGED_FOR_SCHEDULING, + isRecalAcknowledgedForScheduling + ); + }, + saveIsOemGlassSelected(context, isOemGlassSelected) { context.commit(storeMutations.UPDATE_IS_OEM_GLASS_SELECTED, isOemGlassSelected); }, diff --git a/src/styles/ux-variables.scss b/src/styles/ux-variables.scss index 0c275ad51..76035c6ca 100644 --- a/src/styles/ux-variables.scss +++ b/src/styles/ux-variables.scss @@ -27,6 +27,8 @@ $red-600: #ac160b; $red-700: #840900; $red-800: #5b0600; $red-900: #330300; +$red-1000: #a80019; +$red-1100: #791710; // Greens $green-100: #e3f2ea; From 6e0609f8c1bbafe5bbfe89a7d368edc4bbfef4ec Mon Sep 17 00:00:00 2001 From: Chris Redelinghuys Date: Tue, 20 Jan 2026 10:38:26 -0500 Subject: [PATCH 07/11] CASH-2183: Conditional PIA --- src/constants/experiments.js | 3 ++ src/layouts/payment-method/payment-method.vue | 44 ++++++++++++++++++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/constants/experiments.js b/src/constants/experiments.js index a2a648a65..1d689d727 100644 --- a/src/constants/experiments.js +++ b/src/constants/experiments.js @@ -12,6 +12,9 @@ const experimentSettings = { SUPPRESS_VIN_CAPTURE: "SuppressVinCapture", DISPLAY_AVAILABILITY_INDICATORS: "DisplayAvailabilityIndicators", PIA_EXPERIENCE: "PIA Experience", + CONDITIONAL_PROVIDER_NUMBERS: "ConditionalProviderNumbers", + CONDITIONAL_PROVIDER_NUMBERS_2: "ConditionalProviderNumbers2", + CONDITIONAL_PROVIDER_SHUTOFF_DATE: "ConditionalProviderShutoffDate", PIA_INSURANCE: "DisplayPIAInsurance", SUBMIT_ORDER_ENABLE_PIA: "SubmitOrder_Enable_PIA", IS_EMAIL_OPTIONAL: "isEmailOptional", diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index 0fa02e80a..bd4b8212b 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -810,11 +810,51 @@ export default { const piaInsurance = this.getSettingValue(experimentSettings.PIA_INSURANCE); if (this.isInsurance) { - return piaInsurance === "true" && this.currentDeductible > 0; + return ( + (piaInsurance === "true" || this.isConditionalPIAEnabled) && + this.currentDeductible > 0 + ); } else { - return piaExperience === "PIA Optional" || piaExperience === "PIA Required"; + if (piaExperience.includes("PIA Disabled")) { + return this.isConditionalPIAEnabled; + } else { + return piaExperience === "PIA Optional" || piaExperience === "PIA Required"; + } } }, + isConditionalPIAEnabled() { + const conditionalProviderNumbers = this.getSettingValue( + experimentSettings.CONDITIONAL_PROVIDER_NUMBERS + ); + const conditionalProviderNumbers2 = this.getSettingValue( + experimentSettings.CONDITIONAL_PROVIDER_NUMBERS_2 + ); + const conditionalProviderShutoffDate = this.getSettingValue( + experimentSettings.CONDITIONAL_PROVIDER_SHUTOFF_DATE + ); + + const allConditionalProviderNumbers = [ + conditionalProviderNumbers, + conditionalProviderNumbers2, + ] + .filter(Boolean) + .join(","); + const providerNumber = + this.$store.getters.order.serviceLocation.provider.providerNumber; + const appointmentDate = new Date(this.$store.getters.order.schedule.date); + const shutoffDate = new Date(conditionalProviderShutoffDate); + if (allConditionalProviderNumbers && conditionalProviderShutoffDate) { + const providerNumbersArray = allConditionalProviderNumbers + .split(",") + .map((num) => num.trim()); + if (!providerNumbersArray.includes(providerNumber)) { + return false; + } else { + return appointmentDate <= shutoffDate; + } + } + return false; + }, paymentMethod() { if (!this.isPiaEnabled) { return paymentMethods.LATER; From f3166de125140c0cd29aeb4eec5da08152e0f776 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Tue, 20 Jan 2026 10:41:20 -0500 Subject: [PATCH 08/11] CASH-2186 CASSH-2186 when doing a zip change when the recal ack modal is in effect, will have to navigate back to service-zip so we can add any necessary recal parts. --- src/layouts/schedule/schedule.vue | 54 +++++++++++++++----- src/router/constants/navigation-scenarios.js | 1 + src/router/constants/routing-table.js | 4 ++ 3 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue index a812ab5f6..b63e5fb21 100644 --- a/src/layouts/schedule/schedule.vue +++ b/src/layouts/schedule/schedule.vue @@ -1387,7 +1387,7 @@ export default { this.showRecalAcknowledgementPopup = false; }, async forwardButtonAction() { - const showRecalAcknowledgementModal = await this.showRecalAcknowledgementModal(); + const showRecalAcknowledgementModal = this.showRecalAcknowledgementModal(); if ( showRecalAcknowledgementModal && this.isRecalAcknowledgedForScheduling !== RECAL_ACK_YES @@ -1725,7 +1725,27 @@ export default { this.selectedProvider = this.shopProviderData.shopProviders[0]; } }, - handleZipCodeChange(newZipCode) { + async handleZipCodeChange(newZipCode) { + // if we were showing the recal ack modal and now are changing the zip, we need to navigate + // to service-zip so we can get call parts again to add the recal part if needed + if (this.shouldShowRecalAckModal()) { + await baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_SERVICE_ZIP_CODE_INFO, + { + zipCode: newZipCode.zipCode, + state: newZipCode.state, + zipCodeCtu: newZipCode.zipCodeCtu, + }, + false + ); + + this.$router.navigateWithSaving( + this.navigationScenarios.ZIP_CODE_CHANGED_RECAL_ACK, + this.pageName + ); + return; + } + this.resetMobileLocation(); getShopProviderData(newZipCode.zipCode, this.pageName).then((result) => { @@ -1803,18 +1823,8 @@ export default { setSelectedDateToFirstAvailable() { this.selectedDate = this.getFirstAvailableDate(); }, - async showRecalAcknowledgementModal() { - const order = this.$store.getters.order; - const containsRecalPart = containsRecalParts(order.lineItems); - const hasPartWithRecalRequirement = anyPartWithRequiresRecalFlag(order.lineItems); - - // if any of the glass parts contain an item with the requiresRecalibration flag set to true - // and the order does not contain a recalibration part, show the recalibration acknowledgement modal - if ( - !containsRecalPart && - hasPartWithRecalRequirement && - this.isRecalAcknowledgedForScheduling !== RECAL_ACK_YES - ) { + showRecalAcknowledgementModal() { + if (this.shouldShowRecalAckModal()) { this.$refs.navbar.removeLoader(); this.$refs.recalAckModal.openModal(); return true; @@ -1823,6 +1833,22 @@ export default { this.closeRecalAcknowledgementPopup(); return false; }, + shouldShowRecalAckModal() { + // if any of the glass parts contain an item with the requiresRecalibration flag set to true + // and the order does not contain a recalibration part, show the recalibration acknowledgement modal + const order = this.$store.getters.order; + const containsRecalPart = containsRecalParts(order.lineItems); + const hasPartWithRecalRequirement = anyPartWithRequiresRecalFlag(order.lineItems); + + if ( + !containsRecalPart && + hasPartWithRecalRequirement && + this.isRecalAcknowledgedForScheduling !== RECAL_ACK_YES + ) { + return true; + } + return false; + }, async showMobileFirstModal() { if (!this.selectedRouteCodeData?.routeCode) { const pmMobileDays = experimentMixin.methods.getSettingValue( diff --git a/src/router/constants/navigation-scenarios.js b/src/router/constants/navigation-scenarios.js index c2247d59b..0d0ee836f 100644 --- a/src/router/constants/navigation-scenarios.js +++ b/src/router/constants/navigation-scenarios.js @@ -57,6 +57,7 @@ const navigationScenarios = { // Schedule CLICKED_CHANGE_LOCATION: "CLICKED_CHANGE_LOCATION", + ZIP_CODE_CHANGED_RECAL_ACK: "ZIP_CODE_CHANGED_RECAL_ACK", // Payment CLICKED_INSURANCE: "CLICKED_INSURANCE", diff --git a/src/router/constants/routing-table.js b/src/router/constants/routing-table.js index 192e1572e..562615591 100644 --- a/src/router/constants/routing-table.js +++ b/src/router/constants/routing-table.js @@ -486,6 +486,10 @@ const routingTable = function () { scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOBILE_SERVICE, destinationPageData: routeData.MOBILE_DETAILS, }, + { + scenario: navigationScenarios.ZIP_CODE_CHANGED_RECAL_ACK, + destinationPageData: routeData.SERVICE_ZIP, + }, ], }, { From 2914a508781ac8448b3429523fdb4a464f190a10 Mon Sep 17 00:00:00 2001 From: Chris Redelinghuys Date: Tue, 20 Jan 2026 10:56:01 -0500 Subject: [PATCH 09/11] CASH-2183: Null check --- src/layouts/payment-method/payment-method.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index bd4b8212b..2a6d1d9ed 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -815,7 +815,7 @@ export default { this.currentDeductible > 0 ); } else { - if (piaExperience.includes("PIA Disabled")) { + if (piaExperience?.includes("PIA Disabled")) { return this.isConditionalPIAEnabled; } else { return piaExperience === "PIA Optional" || piaExperience === "PIA Required"; From 19dad3a5ca5bad982b05415ad6d0921a072bd15e Mon Sep 17 00:00:00 2001 From: CarlNation Date: Wed, 21 Jan 2026 12:30:13 -0500 Subject: [PATCH 10/11] CASH-1297 CASH-1297 this is a temporary defect fix for this card --- src/layouts/payment-method/payment-method.vue | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index 2a6d1d9ed..a66c1b758 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -609,6 +609,19 @@ export default { return; } + const billToAccountNumber = await baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.GET_BILL_TO_ACCOUNT_NUMBER, + {}, + "payment-method", + false + ); + + baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_BILL_TO_ACCOUNT_NUMBER, + billToAccountNumber, + false + ); + this.dispatchStoreAction(storeActions.RESET_SAVE_SESSION_PROMISE); const shouldUseAdyen = experimentMixin.methods.hasSettingEqualTo( From fe9d1fd4763456c1643ef09bdd8cb4811a80b05c Mon Sep 17 00:00:00 2001 From: CarlNation Date: Thu, 22 Jan 2026 09:29:14 -0500 Subject: [PATCH 11/11] Revert "CASH-1297" This reverts commit 19dad3a5ca5bad982b05415ad6d0921a072bd15e. --- src/layouts/payment-method/payment-method.vue | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index a66c1b758..2a6d1d9ed 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -609,19 +609,6 @@ export default { return; } - const billToAccountNumber = await baseMixin.methods.dispatchStoreActionWithLogging( - storeActions.GET_BILL_TO_ACCOUNT_NUMBER, - {}, - "payment-method", - false - ); - - baseMixin.methods.dispatchStoreAction( - storeActions.SAVE_BILL_TO_ACCOUNT_NUMBER, - billToAccountNumber, - false - ); - this.dispatchStoreAction(storeActions.RESET_SAVE_SESSION_PROMISE); const shouldUseAdyen = experimentMixin.methods.hasSettingEqualTo(