From de708f9d9581306847a3d88226c129ff981b351a Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Tue, 18 Mar 2025 19:42:44 -0400 Subject: [PATCH 1/3] CASH-152: post- tech review items --- src/constants/endpoints.js | 2 +- src/constants/schedule-constants.js | 5 +- src/constants/store-actions.js | 2 +- .../date-picker/mixins/constants.js | 50 +++++++++- .../date-picker-for-pricing-by-day.vue | 20 ++-- src/helpers/pricing-helper.js | 4 +- src/layouts/schedule/schedule.vue | 91 ++++++++++--------- src/store/index.js | 6 +- 8 files changed, 115 insertions(+), 65 deletions(-) diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index bfc02d034..f54be3c38 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -72,7 +72,7 @@ const endpoints = { url: "/parts/api/v1/parts/mobile-fee", method: "GET", }, - GetPricingByDayUpchargePart: { + GetPricingByDayPart: { url: "/parts/api/v1/parts/get-pricing-by-day-part-number", method: "GET", }, diff --git a/src/constants/schedule-constants.js b/src/constants/schedule-constants.js index b7eaa4882..37985214f 100644 --- a/src/constants/schedule-constants.js +++ b/src/constants/schedule-constants.js @@ -8,7 +8,8 @@ const PREMIUM_TIME_SLOT_ID_FLAG = "-PREMIUM"; const PREMIUM_FEE_PART_TYPE = "EARLY BIRD"; -const PRICING_BY_DAY_UPCHARGE_FEE_PART_TYPE = "DISC CASHSAVE20"; + // TODO; This will need updating with real PricingByDay part type + const PRICING_BY_DAY_PART_TYPE = "DISC CASHSAVE20"; const RouteCodeFlags = { ALL_DAY_DROP_OFF: "ALL DAY DROP OFF", @@ -19,6 +20,6 @@ export { AppointmentTypeStrings, PREMIUM_TIME_SLOT_ID_FLAG, PREMIUM_FEE_PART_TYPE, - PRICING_BY_DAY_UPCHARGE_FEE_PART_TYPE, + PRICING_BY_DAY_PART_TYPE, RouteCodeFlags, }; diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index af68c8997..baa219aa1 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -30,7 +30,7 @@ const storeActions = { GET_PART_FROM_CAPABILITY_QUESTION_ANSWER: "getPartFromCapabilityQuestionAnswer", GET_MOLDING_QUESTIONS: "getMoldingQuestions", GET_MOBILE_FEE_PART: "getMobileFeePart", - GET_PRICING_BY_DAY_UPCHARGE_PART: "getPricingByDayUpchargePart", + GET_PRICING_BY_DAY_PART: "getPricingByDayPart", GET_SERVICE_PACKAGE_DISCOUNT_PART: "getServicePackageDiscountPart", GET_SERVICEABILITY_DETAILS: "getServiceabilityDetails", GET_SHOP_TIME_SLOTS: "getShopTimeSlots", diff --git a/src/digital-components/date-picker/mixins/constants.js b/src/digital-components/date-picker/mixins/constants.js index f9c9f6c9f..b9092b5eb 100644 --- a/src/digital-components/date-picker/mixins/constants.js +++ b/src/digital-components/date-picker/mixins/constants.js @@ -21,8 +21,50 @@ const MONTHS_OF_YEAR = [ "December", ]; -const DAYS_OF_WEEK = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; +const DAYS_OF_WEEK = [ + // Monday, Friday, Saturday are the pricing by day premium days + { + label: "Sunday", + cssClass: "sunday", + index: 0, + isPricingByDayUpchargeDay: false, + }, + { + label: "Monday", + cssClass: "monday", + index: 1, + isPricingByDayUpchargeDay: true, + }, + { + label: "Tuesday", + cssClass: "tuesday", + index: 2, + isPricingByDayUpchargeDay: false, + }, + { + label: "Wednesday", + cssClass: "wednesday", + index: 3, + isPricingByDayUpchargeDay: false, + }, + { + label: "Thursday", + cssClass: "thursday", + index: 4, + isPricingByDayUpchargeDay: false, + }, + { + label: "Friday", + cssClass: "friday", + index: 5, + isPricingByDayUpchargeDay: true, + }, + { + label: "Saturday", + cssClass: "saturday", + index: 6, + isPricingByDayUpchargeDay: true, + }, +]; -const PREMIUM_DAY_INDEXES = [1, 5, 6]; // assign Monday, Friday, Saturday to be premium days - -export { TIMINGFUNC_MAP, BUFFER_OFFSET, MONTHS_OF_YEAR, DAYS_OF_WEEK, PREMIUM_DAY_INDEXES }; +export { TIMINGFUNC_MAP, BUFFER_OFFSET, MONTHS_OF_YEAR, DAYS_OF_WEEK }; diff --git a/src/experiment-components/date-picker-for-pricing-by-day.vue b/src/experiment-components/date-picker-for-pricing-by-day.vue index c94f10a17..5bdcec336 100644 --- a/src/experiment-components/date-picker-for-pricing-by-day.vue +++ b/src/experiment-components/date-picker-for-pricing-by-day.vue @@ -108,7 +108,7 @@ import { TIMINGFUNC_MAP, BUFFER_OFFSET, MONTHS_OF_YEAR, - PREMIUM_DAY_INDEXES, + DAYS_OF_WEEK, } from "@/digital-components/date-picker/mixins/constants"; import { selectableDaysOptions, @@ -163,7 +163,7 @@ export default { default: "", }, showPricingByDay: Boolean, - baseDayPrice: Number, + pricingByDayBasePrice: Number, pricingByDayUpcharge: Number, isPricingByDayExperiment: Boolean, }, @@ -437,8 +437,6 @@ export default { hideSomeDaysForInitialView: hideSomeDaysForInitialView, hideSecondMonth: hideSecondMonth, preSelectedDate: config.preSelectedDate, - baseDayPrice: config.baseDayPrice, - pricingByDayUpcharge: config.pricingByDayUpcharge, }; return initialData; }); @@ -463,7 +461,7 @@ export default { initialViewEndDate: config.initialViewEndDate, hideSecondMonth: hideSecondMonth, preSelectedDate: config.preSelectedDate, - baseDayPrice: config.baseDayPrice, + pricingByDayBasePrice: config.pricingByDayBasePrice, pricingByDayUpcharge: config.pricingByDayUpcharge, }; if (direction === "future") { @@ -599,15 +597,15 @@ export default { "-" + ("0" + i).slice(-2); const dayIndex = convertDateStringToDate(dateString).getDay(); + const dayObject = DAYS_OF_WEEK[dayIndex]; const isSelectable = this.selectableDatesData.findIndex((date) => date.date === dateString) > -1 ? true : false; - - const isPricingByDayUpchargeDay = PREMIUM_DAY_INDEXES.includes(dayIndex); - let displayPrice = isPricingByDayUpchargeDay - ? options.baseDayPrice + options.pricingByDayUpcharge - : options.baseDayPrice; + const isPricingByDayUpchargeDay = dayObject.isPricingByDayUpchargeDay; + const displayPrice = isPricingByDayUpchargeDay + ? options.pricingByDayBasePrice + options.pricingByDayUpcharge + : options.pricingByDayBasePrice; const priceString = "$" + displayPrice; if (offset === 0 && i === this.todayDateNum) { @@ -620,7 +618,7 @@ export default { dayClasses += " unavailable-day"; } if (dayIndex === 0) { - dayClasses += " sunday"; + dayClasses += " " + dayObject.cssClass; } if ( this.hideSomeDaysForInitialView && diff --git a/src/helpers/pricing-helper.js b/src/helpers/pricing-helper.js index c470aaf31..fda5b3b9c 100644 --- a/src/helpers/pricing-helper.js +++ b/src/helpers/pricing-helper.js @@ -62,10 +62,10 @@ export function getSalesTax(lineItemsObject) { ); } -export async function getPriceUpchargeByDayPart(pageNameToLog) { +export async function getPricingByDayPartWithPrice(pageNameToLog) { // Get the Pricing By Day Part const basePriceByDayPart = await baseMixin.methods.dispatchStoreActionWithLogging( - storeActions.GET_PRICING_BY_DAY_UPCHARGE_PART, + storeActions.GET_PRICING_BY_DAY_PART, null, pageNameToLog, false diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue index be7009a26..2704cdaf6 100644 --- a/src/layouts/schedule/schedule.vue +++ b/src/layouts/schedule/schedule.vue @@ -26,7 +26,7 @@ class="text-link-small" :customSelectableDatesCallback="getAvailableDatesMethod" validationRules="date-required" - :baseDayPrice="baseDayPrice" + :pricingByDayBasePrice="pricingByDayBasePrice" :pricingByDayUpcharge="pricingByDayUpcharge" :showPricingByDay="showPricingByDay" :isPricingByDayExperiment="isPricingByDayExperiment" @@ -98,14 +98,14 @@ import { import { AppointmentTypeStrings, PREMIUM_FEE_PART_TYPE, - PRICING_BY_DAY_UPCHARGE_FEE_PART_TYPE, + PRICING_BY_DAY_PART_TYPE, } from "@/constants/schedule-constants"; import { errorMessages } from "@/constants/error-messages"; import { required } from "@/helpers/validation-rules"; import store from "@/store"; import experimentMixin from "@/mixins/experiment-mixin.js"; import { experimentSettings } from "@/constants/experiments"; -import { getAmountDue, getPriceUpchargeByDayPart } from "@/helpers/pricing-helper.js"; +import { getAmountDue, getPricingByDayPartWithPrice } from "@/helpers/pricing-helper.js"; import { getItemsWithoutRecalParts } from "@/helpers/recal-helper"; import { partNumberStrings } from "@/constants/part-number-strings"; import { deepClone } from "@/helpers/object-helper"; @@ -224,21 +224,28 @@ export default { waitListRequested: null, displayWaitList: null, pricingByDayUpchargeLineItem: null, - includePricingByDaySurcharge: null, + includePricingByDayUpcharge: null, isPricingByDayExperiment: null, - baseDayPrice: null, + pricingByDayBasePrice: null, pricingByDayUpcharge: null, showPricingByDay: null, }; }, async beforeRouteEnter(to, from, next) { - // Get data needed for Pricing By Day - const lineItems = deepClone(await store.getters.order.lineItems); - const isRecalibrationOnOrder = await store.getters.isRecalibrationOnOrder; + const isPricingByDayExperiment = experimentMixin.methods.hasSettingEqualTo( + experimentSettings.PRICING_BY_DAY, + "true" + ); + const showPricingByDay = !store.getters.payment.isInsurance && isPricingByDayExperiment; + + // Get pricingByDayBasePrice needed for Pricing By Day + const lineItems = deepClone(store.getters.order.lineItems); + const isRecalibrationOnOrder = store.getters.isRecalibrationOnOrder; const shouldHideRecalibration = - experimentMixin.methods - .getSettingValue(experimentSettings.RECAL_PRICE_REMOVE) - ?.toLowerCase() === "true" && isRecalibrationOnOrder; + experimentMixin.methods.hasSettingEqualTo( + experimentSettings.RECAL_PRICE_REMOVE, + "true" + ) && isRecalibrationOnOrder; const glassParts = isRecalibrationOnOrder && shouldHideRecalibration ? getItemsWithoutRecalParts(lineItems.glassParts) @@ -253,28 +260,18 @@ export default { vaps: lineItems.vaps ?? [], promos: lineItems.promos ?? [], }; - const isPricingByDayExperiment = - (await experimentMixin.methods - .getSettingValue(experimentSettings.PRICING_BY_DAY) - ?.toLowerCase()) === "true"; - const priceString = await getAmountDue(lineItemsToBePriced, false); // pass the IncludeTax param as false + const priceString = getAmountDue(lineItemsToBePriced, false); // pass the IncludeTax param as false const priceStringIntegerRoundedDown = priceString?.split(".")[0]; // same method used as getDisplayPrice() in service-package-radio used on /quote - const baseDayPrice = parseInt(priceStringIntegerRoundedDown); - const showPricingByDay = !store.getters.payment.isInsurance && isPricingByDayExperiment; - const pricingByDayUpchargeLineItem = await getPriceUpchargeByDayPart(); - const pricingByDayUpcharge = await baseMixin.methods.getTotalLineItemPrice( - pricingByDayUpchargeLineItem, - false - ); + const pricingByDayBasePrice = parseInt(priceStringIntegerRoundedDown); - // Check to see if includePricingByDaySurcharge should already be set (based on order lineItems) - let includePricingByDaySurcharge = false; + // Check to see if includePricingByDayUpcharge should already be set (based on order lineItems) + let includePricingByDayUpcharge = false; if (supportingItemsWithoutFees) { const pricingByDayUpchargeFeeIndex = supportingItemsWithoutFees.findIndex( - (item) => item.partType == PRICING_BY_DAY_UPCHARGE_FEE_PART_TYPE + (item) => item.partType == PRICING_BY_DAY_PART_TYPE ); if (pricingByDayUpchargeFeeIndex > -1) { - includePricingByDaySurcharge = true; + includePricingByDayUpcharge = true; } } @@ -292,7 +289,7 @@ export default { store.getters.order.serviceLocation.provider?.address?.zipCodeCtu ); - // While Pricing By Day Experiment is ongoing, using the updated datePicker + // While Pricing By Day Experiment is active, using the updated datePicker const datePickerInitialDataPromise = await datePickerForPricingByDay.methods.loadInitialData({ // setup config options for date-picker @@ -300,10 +297,11 @@ export default { initialViewRowsToShow: 5, customSelectableDatesCallback: getAvailableDates, preSelectedDate: preSelectedDate, - baseDayPrice: baseDayPrice, - pricingByDayUpcharge: pricingByDayUpcharge, }); + // Get pricingByDayUpcharge needed for Pricing By Day + const pricingByDayUpchargePartPromise = getPricingByDayPartWithPrice(); + const premiumFeePromise = baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_MOBILE_PREMIUM_FEE, null, @@ -338,6 +336,10 @@ export default { resultKey: "datePickerInitialData", promise: datePickerInitialDataPromise, }, + { + resultKey: "pricingByDayUpchargePart", + promise: pricingByDayUpchargePartPromise, + }, { resultKey: "premiumFeeWithPrice", promise: premiumFeeWithPricePromise, @@ -346,10 +348,19 @@ export default { const resultMap = await settleAllPromises(promiseResultMap); + const pricingByDayUpcharge = await baseMixin.methods.getTotalLineItemPrice( + resultMap.pricingByDayUpchargePart, + false + ); + + const datePickerInitialData = resultMap.datePickerInitialData; + datePickerInitialData.pricingByDayBasePrice = pricingByDayBasePrice; + datePickerInitialData.pricingByDayUpcharge = pricingByDayUpcharge; + // Call the "next" function to complete the transition to this page. next((vm) => { vm.setCmsContent(resultMap.cmsContent); - vm.$refs.datePicker.initializeComponent(resultMap.datePickerInitialData); + vm.$refs.datePicker.initializeComponent(datePickerInitialData); vm.$refs.locationAlerts.initializeComponent(resultMap.alertReasons); vm.selectableDatesData = resultMap.datePickerInitialData.initialShopTimeSlotsResponse; vm.mobilePremiumAppointmentFee = resultMap.premiumFeeWithPrice @@ -357,10 +368,10 @@ export default { : null; vm.updateFooterButtonText(vm.selectedTimeSlotInfo); vm.setDisplayWaitList(); - vm.pricingByDayUpchargeLineItem = pricingByDayUpchargeLineItem; - vm.includePricingByDaySurcharge = includePricingByDaySurcharge; + vm.pricingByDayUpchargeLineItem = resultMap.pricingByDayUpchargePart; + vm.includePricingByDayUpcharge = includePricingByDayUpcharge; vm.isPricingByDayExperiment = isPricingByDayExperiment; - vm.baseDayPrice = baseDayPrice; + vm.pricingByDayBasePrice = pricingByDayBasePrice; vm.pricingByDayUpcharge = pricingByDayUpcharge; vm.showPricingByDay = showPricingByDay; }); @@ -377,9 +388,7 @@ export default { return this.$store.getters.order.serviceLocation.appointmentType; }, timeSlotsForSelectedDate() { - if (!this.selectedDate) { - return null; - } + if (!this.selectedDate) return null; return this.selectableDatesData.days?.find( (selectableDate) => selectableDate.date === this.selectedDate @@ -612,10 +621,10 @@ export default { // if we have a pricing by day upcharge, then save/update supporting items with it const pricingByDayUpchargeFeeIndex = supportingItems?.findIndex( - (item) => item.partType == PRICING_BY_DAY_UPCHARGE_FEE_PART_TYPE + (item) => item.partType == PRICING_BY_DAY_PART_TYPE ); - if (this.includePricingByDaySurcharge) { + if (this.includePricingByDayUpcharge) { if (pricingByDayUpchargeFeeIndex > -1) { supportingItems[pricingByDayUpchargeFeeIndex].laborAmount = this.pricingByDayUpchargeLineItem.laborAmount; @@ -678,9 +687,9 @@ export default { handleDateClicked(date) { // do something to mark this as upcharge day or not... if (date.isPricingByDayUpchargeDay) { - this.includePricingByDaySurcharge = true; + this.includePricingByDayUpcharge = true; } else { - this.includePricingByDaySurcharge = false; + this.includePricingByDayUpcharge = false; } this.openInshopTimeSlotsModal(); diff --git a/src/store/index.js b/src/store/index.js index 1a0a18d7a..da849c127 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1749,11 +1749,11 @@ export const actions = { pageNameToLog: pageNameToLog, }); }, - async getPricingByDayUpchargePart(context, { pageNameToLog }) { + async getPricingByDayPart(context, { pageNameToLog }) { return await globalMethods .callHttpClient({ - method: endpoints.GetPricingByDayUpchargePart.method, - endpoint: endpoints.GetPricingByDayUpchargePart.url, + method: endpoints.GetPricingByDayPart.method, + endpoint: endpoints.GetPricingByDayPart.url, logApiCall: true, pageNameToLog: pageNameToLog, }) From 48fca6264bd7c28c0b522657ba0f14970a4032b3 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Tue, 18 Mar 2025 19:55:10 -0400 Subject: [PATCH 2/3] CASH-152: format change --- src/constants/schedule-constants.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/constants/schedule-constants.js b/src/constants/schedule-constants.js index 37985214f..a0aaf8316 100644 --- a/src/constants/schedule-constants.js +++ b/src/constants/schedule-constants.js @@ -8,8 +8,8 @@ const PREMIUM_TIME_SLOT_ID_FLAG = "-PREMIUM"; const PREMIUM_FEE_PART_TYPE = "EARLY BIRD"; - // TODO; This will need updating with real PricingByDay part type - const PRICING_BY_DAY_PART_TYPE = "DISC CASHSAVE20"; +// TODO; This will need updating with real PricingByDay part type +const PRICING_BY_DAY_PART_TYPE = "DISC CASHSAVE20"; const RouteCodeFlags = { ALL_DAY_DROP_OFF: "ALL DAY DROP OFF", From cedd6ebfb31d10d1e51bffc79ff5e07cb318242e Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Wed, 19 Mar 2025 08:25:11 -0400 Subject: [PATCH 3/3] CASH-152: update endpoint --- src/constants/endpoints.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index f54be3c38..594227f7b 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -73,7 +73,7 @@ const endpoints = { method: "GET", }, GetPricingByDayPart: { - url: "/parts/api/v1/parts/get-pricing-by-day-part-number", + url: "/parts/api/v1/parts/pricing-by-day-part-number", method: "GET", }, GetServicePackageDiscountPart: {