Merge pull request #2362 from Safelite/feature/CASH-152-ajc

Feature/CASH-152 refactors after tech review
This commit is contained in:
AdamCaouetteSafelite 2025-03-19 13:47:34 -04:00 committed by GitHub
commit d1f356d2e2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 116 additions and 66 deletions

View file

@ -72,8 +72,8 @@ const endpoints = {
url: "/parts/api/v1/parts/mobile-fee", url: "/parts/api/v1/parts/mobile-fee",
method: "GET", method: "GET",
}, },
GetPricingByDayUpchargePart: { GetPricingByDayPart: {
url: "/parts/api/v1/parts/get-pricing-by-day-part-number", url: "/parts/api/v1/parts/pricing-by-day-part-number",
method: "GET", method: "GET",
}, },
GetServicePackageDiscountPart: { GetServicePackageDiscountPart: {

View file

@ -8,7 +8,8 @@ const PREMIUM_TIME_SLOT_ID_FLAG = "-PREMIUM";
const PREMIUM_FEE_PART_TYPE = "EARLY BIRD"; 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 = { const RouteCodeFlags = {
ALL_DAY_DROP_OFF: "ALL DAY DROP OFF", ALL_DAY_DROP_OFF: "ALL DAY DROP OFF",
@ -19,6 +20,6 @@ export {
AppointmentTypeStrings, AppointmentTypeStrings,
PREMIUM_TIME_SLOT_ID_FLAG, PREMIUM_TIME_SLOT_ID_FLAG,
PREMIUM_FEE_PART_TYPE, PREMIUM_FEE_PART_TYPE,
PRICING_BY_DAY_UPCHARGE_FEE_PART_TYPE, PRICING_BY_DAY_PART_TYPE,
RouteCodeFlags, RouteCodeFlags,
}; };

View file

@ -30,7 +30,7 @@ const storeActions = {
GET_PART_FROM_CAPABILITY_QUESTION_ANSWER: "getPartFromCapabilityQuestionAnswer", GET_PART_FROM_CAPABILITY_QUESTION_ANSWER: "getPartFromCapabilityQuestionAnswer",
GET_MOLDING_QUESTIONS: "getMoldingQuestions", GET_MOLDING_QUESTIONS: "getMoldingQuestions",
GET_MOBILE_FEE_PART: "getMobileFeePart", 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_SERVICE_PACKAGE_DISCOUNT_PART: "getServicePackageDiscountPart",
GET_SERVICEABILITY_DETAILS: "getServiceabilityDetails", GET_SERVICEABILITY_DETAILS: "getServiceabilityDetails",
GET_SHOP_TIME_SLOTS: "getShopTimeSlots", GET_SHOP_TIME_SLOTS: "getShopTimeSlots",

View file

@ -21,8 +21,50 @@ const MONTHS_OF_YEAR = [
"December", "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 };
export { TIMINGFUNC_MAP, BUFFER_OFFSET, MONTHS_OF_YEAR, DAYS_OF_WEEK, PREMIUM_DAY_INDEXES };

View file

@ -108,7 +108,7 @@ import {
TIMINGFUNC_MAP, TIMINGFUNC_MAP,
BUFFER_OFFSET, BUFFER_OFFSET,
MONTHS_OF_YEAR, MONTHS_OF_YEAR,
PREMIUM_DAY_INDEXES, DAYS_OF_WEEK,
} from "@/digital-components/date-picker/mixins/constants"; } from "@/digital-components/date-picker/mixins/constants";
import { import {
selectableDaysOptions, selectableDaysOptions,
@ -163,7 +163,7 @@ export default {
default: "", default: "",
}, },
showPricingByDay: Boolean, showPricingByDay: Boolean,
baseDayPrice: Number, pricingByDayBasePrice: Number,
pricingByDayUpcharge: Number, pricingByDayUpcharge: Number,
isPricingByDayExperiment: Boolean, isPricingByDayExperiment: Boolean,
}, },
@ -437,8 +437,6 @@ export default {
hideSomeDaysForInitialView: hideSomeDaysForInitialView, hideSomeDaysForInitialView: hideSomeDaysForInitialView,
hideSecondMonth: hideSecondMonth, hideSecondMonth: hideSecondMonth,
preSelectedDate: config.preSelectedDate, preSelectedDate: config.preSelectedDate,
baseDayPrice: config.baseDayPrice,
pricingByDayUpcharge: config.pricingByDayUpcharge,
}; };
return initialData; return initialData;
}); });
@ -463,7 +461,7 @@ export default {
initialViewEndDate: config.initialViewEndDate, initialViewEndDate: config.initialViewEndDate,
hideSecondMonth: hideSecondMonth, hideSecondMonth: hideSecondMonth,
preSelectedDate: config.preSelectedDate, preSelectedDate: config.preSelectedDate,
baseDayPrice: config.baseDayPrice, pricingByDayBasePrice: config.pricingByDayBasePrice,
pricingByDayUpcharge: config.pricingByDayUpcharge, pricingByDayUpcharge: config.pricingByDayUpcharge,
}; };
if (direction === "future") { if (direction === "future") {
@ -599,15 +597,15 @@ export default {
"-" + "-" +
("0" + i).slice(-2); ("0" + i).slice(-2);
const dayIndex = convertDateStringToDate(dateString).getDay(); const dayIndex = convertDateStringToDate(dateString).getDay();
const dayObject = DAYS_OF_WEEK[dayIndex];
const isSelectable = const isSelectable =
this.selectableDatesData.findIndex((date) => date.date === dateString) > -1 this.selectableDatesData.findIndex((date) => date.date === dateString) > -1
? true ? true
: false; : false;
const isPricingByDayUpchargeDay = dayObject.isPricingByDayUpchargeDay;
const isPricingByDayUpchargeDay = PREMIUM_DAY_INDEXES.includes(dayIndex); const displayPrice = isPricingByDayUpchargeDay
let displayPrice = isPricingByDayUpchargeDay ? options.pricingByDayBasePrice + options.pricingByDayUpcharge
? options.baseDayPrice + options.pricingByDayUpcharge : options.pricingByDayBasePrice;
: options.baseDayPrice;
const priceString = "$" + displayPrice; const priceString = "$" + displayPrice;
if (offset === 0 && i === this.todayDateNum) { if (offset === 0 && i === this.todayDateNum) {
@ -620,7 +618,7 @@ export default {
dayClasses += " unavailable-day"; dayClasses += " unavailable-day";
} }
if (dayIndex === 0) { if (dayIndex === 0) {
dayClasses += " sunday"; dayClasses += " " + dayObject.cssClass;
} }
if ( if (
this.hideSomeDaysForInitialView && this.hideSomeDaysForInitialView &&

View file

@ -62,10 +62,10 @@ export function getSalesTax(lineItemsObject) {
); );
} }
export async function getPriceUpchargeByDayPart(pageNameToLog) { export async function getPricingByDayPartWithPrice(pageNameToLog) {
// Get the Pricing By Day Part // Get the Pricing By Day Part
const basePriceByDayPart = await baseMixin.methods.dispatchStoreActionWithLogging( const basePriceByDayPart = await baseMixin.methods.dispatchStoreActionWithLogging(
storeActions.GET_PRICING_BY_DAY_UPCHARGE_PART, storeActions.GET_PRICING_BY_DAY_PART,
null, null,
pageNameToLog, pageNameToLog,
false false

View file

@ -26,7 +26,7 @@
class="text-link-small" class="text-link-small"
:customSelectableDatesCallback="getAvailableDatesMethod" :customSelectableDatesCallback="getAvailableDatesMethod"
validationRules="date-required" validationRules="date-required"
:baseDayPrice="baseDayPrice" :pricingByDayBasePrice="pricingByDayBasePrice"
:pricingByDayUpcharge="pricingByDayUpcharge" :pricingByDayUpcharge="pricingByDayUpcharge"
:showPricingByDay="showPricingByDay" :showPricingByDay="showPricingByDay"
:isPricingByDayExperiment="isPricingByDayExperiment" :isPricingByDayExperiment="isPricingByDayExperiment"
@ -98,14 +98,14 @@ import {
import { import {
AppointmentTypeStrings, AppointmentTypeStrings,
PREMIUM_FEE_PART_TYPE, PREMIUM_FEE_PART_TYPE,
PRICING_BY_DAY_UPCHARGE_FEE_PART_TYPE, PRICING_BY_DAY_PART_TYPE,
} from "@/constants/schedule-constants"; } from "@/constants/schedule-constants";
import { errorMessages } from "@/constants/error-messages"; import { errorMessages } from "@/constants/error-messages";
import { required } from "@/helpers/validation-rules"; import { required } from "@/helpers/validation-rules";
import store from "@/store"; import store from "@/store";
import experimentMixin from "@/mixins/experiment-mixin.js"; import experimentMixin from "@/mixins/experiment-mixin.js";
import { experimentSettings } from "@/constants/experiments"; 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 { getItemsWithoutRecalParts } from "@/helpers/recal-helper";
import { partNumberStrings } from "@/constants/part-number-strings"; import { partNumberStrings } from "@/constants/part-number-strings";
import { deepClone } from "@/helpers/object-helper"; import { deepClone } from "@/helpers/object-helper";
@ -224,21 +224,28 @@ export default {
waitListRequested: null, waitListRequested: null,
displayWaitList: null, displayWaitList: null,
pricingByDayUpchargeLineItem: null, pricingByDayUpchargeLineItem: null,
includePricingByDaySurcharge: null, includePricingByDayUpcharge: null,
isPricingByDayExperiment: null, isPricingByDayExperiment: null,
baseDayPrice: null, pricingByDayBasePrice: null,
pricingByDayUpcharge: null, pricingByDayUpcharge: null,
showPricingByDay: null, showPricingByDay: null,
}; };
}, },
async beforeRouteEnter(to, from, next) { async beforeRouteEnter(to, from, next) {
// Get data needed for Pricing By Day const isPricingByDayExperiment = experimentMixin.methods.hasSettingEqualTo(
const lineItems = deepClone(await store.getters.order.lineItems); experimentSettings.PRICING_BY_DAY,
const isRecalibrationOnOrder = await store.getters.isRecalibrationOnOrder; "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 = const shouldHideRecalibration =
experimentMixin.methods experimentMixin.methods.hasSettingEqualTo(
.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE) experimentSettings.RECAL_PRICE_REMOVE,
?.toLowerCase() === "true" && isRecalibrationOnOrder; "true"
) && isRecalibrationOnOrder;
const glassParts = const glassParts =
isRecalibrationOnOrder && shouldHideRecalibration isRecalibrationOnOrder && shouldHideRecalibration
? getItemsWithoutRecalParts(lineItems.glassParts) ? getItemsWithoutRecalParts(lineItems.glassParts)
@ -253,28 +260,18 @@ export default {
vaps: lineItems.vaps ?? [], vaps: lineItems.vaps ?? [],
promos: lineItems.promos ?? [], promos: lineItems.promos ?? [],
}; };
const isPricingByDayExperiment = const priceString = getAmountDue(lineItemsToBePriced, false); // pass the IncludeTax param as false
(await experimentMixin.methods
.getSettingValue(experimentSettings.PRICING_BY_DAY)
?.toLowerCase()) === "true";
const priceString = await 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 priceStringIntegerRoundedDown = priceString?.split(".")[0]; // same method used as getDisplayPrice() in service-package-radio used on /quote
const baseDayPrice = parseInt(priceStringIntegerRoundedDown); const pricingByDayBasePrice = parseInt(priceStringIntegerRoundedDown);
const showPricingByDay = !store.getters.payment.isInsurance && isPricingByDayExperiment;
const pricingByDayUpchargeLineItem = await getPriceUpchargeByDayPart();
const pricingByDayUpcharge = await baseMixin.methods.getTotalLineItemPrice(
pricingByDayUpchargeLineItem,
false
);
// Check to see if includePricingByDaySurcharge should already be set (based on order lineItems) // Check to see if includePricingByDayUpcharge should already be set (based on order lineItems)
let includePricingByDaySurcharge = false; let includePricingByDayUpcharge = false;
if (supportingItemsWithoutFees) { if (supportingItemsWithoutFees) {
const pricingByDayUpchargeFeeIndex = supportingItemsWithoutFees.findIndex( 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) { if (pricingByDayUpchargeFeeIndex > -1) {
includePricingByDaySurcharge = true; includePricingByDayUpcharge = true;
} }
} }
@ -292,7 +289,7 @@ export default {
store.getters.order.serviceLocation.provider?.address?.zipCodeCtu 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 = const datePickerInitialDataPromise =
await datePickerForPricingByDay.methods.loadInitialData({ await datePickerForPricingByDay.methods.loadInitialData({
// setup config options for date-picker // setup config options for date-picker
@ -300,10 +297,11 @@ export default {
initialViewRowsToShow: 5, initialViewRowsToShow: 5,
customSelectableDatesCallback: getAvailableDates, customSelectableDatesCallback: getAvailableDates,
preSelectedDate: preSelectedDate, preSelectedDate: preSelectedDate,
baseDayPrice: baseDayPrice,
pricingByDayUpcharge: pricingByDayUpcharge,
}); });
// Get pricingByDayUpcharge needed for Pricing By Day
const pricingByDayUpchargePartPromise = getPricingByDayPartWithPrice();
const premiumFeePromise = baseMixin.methods.dispatchStoreActionWithLogging( const premiumFeePromise = baseMixin.methods.dispatchStoreActionWithLogging(
storeActions.GET_MOBILE_PREMIUM_FEE, storeActions.GET_MOBILE_PREMIUM_FEE,
null, null,
@ -338,6 +336,10 @@ export default {
resultKey: "datePickerInitialData", resultKey: "datePickerInitialData",
promise: datePickerInitialDataPromise, promise: datePickerInitialDataPromise,
}, },
{
resultKey: "pricingByDayUpchargePart",
promise: pricingByDayUpchargePartPromise,
},
{ {
resultKey: "premiumFeeWithPrice", resultKey: "premiumFeeWithPrice",
promise: premiumFeeWithPricePromise, promise: premiumFeeWithPricePromise,
@ -346,10 +348,19 @@ export default {
const resultMap = await settleAllPromises(promiseResultMap); 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. // Call the "next" function to complete the transition to this page.
next((vm) => { next((vm) => {
vm.setCmsContent(resultMap.cmsContent); vm.setCmsContent(resultMap.cmsContent);
vm.$refs.datePicker.initializeComponent(resultMap.datePickerInitialData); vm.$refs.datePicker.initializeComponent(datePickerInitialData);
vm.$refs.locationAlerts.initializeComponent(resultMap.alertReasons); vm.$refs.locationAlerts.initializeComponent(resultMap.alertReasons);
vm.selectableDatesData = resultMap.datePickerInitialData.initialShopTimeSlotsResponse; vm.selectableDatesData = resultMap.datePickerInitialData.initialShopTimeSlotsResponse;
vm.mobilePremiumAppointmentFee = resultMap.premiumFeeWithPrice vm.mobilePremiumAppointmentFee = resultMap.premiumFeeWithPrice
@ -357,10 +368,10 @@ export default {
: null; : null;
vm.updateFooterButtonText(vm.selectedTimeSlotInfo); vm.updateFooterButtonText(vm.selectedTimeSlotInfo);
vm.setDisplayWaitList(); vm.setDisplayWaitList();
vm.pricingByDayUpchargeLineItem = pricingByDayUpchargeLineItem; vm.pricingByDayUpchargeLineItem = resultMap.pricingByDayUpchargePart;
vm.includePricingByDaySurcharge = includePricingByDaySurcharge; vm.includePricingByDayUpcharge = includePricingByDayUpcharge;
vm.isPricingByDayExperiment = isPricingByDayExperiment; vm.isPricingByDayExperiment = isPricingByDayExperiment;
vm.baseDayPrice = baseDayPrice; vm.pricingByDayBasePrice = pricingByDayBasePrice;
vm.pricingByDayUpcharge = pricingByDayUpcharge; vm.pricingByDayUpcharge = pricingByDayUpcharge;
vm.showPricingByDay = showPricingByDay; vm.showPricingByDay = showPricingByDay;
}); });
@ -377,9 +388,7 @@ export default {
return this.$store.getters.order.serviceLocation.appointmentType; return this.$store.getters.order.serviceLocation.appointmentType;
}, },
timeSlotsForSelectedDate() { timeSlotsForSelectedDate() {
if (!this.selectedDate) { if (!this.selectedDate) return null;
return null;
}
return this.selectableDatesData.days?.find( return this.selectableDatesData.days?.find(
(selectableDate) => selectableDate.date === this.selectedDate (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 // if we have a pricing by day upcharge, then save/update supporting items with it
const pricingByDayUpchargeFeeIndex = supportingItems?.findIndex( 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) { if (pricingByDayUpchargeFeeIndex > -1) {
supportingItems[pricingByDayUpchargeFeeIndex].laborAmount = supportingItems[pricingByDayUpchargeFeeIndex].laborAmount =
this.pricingByDayUpchargeLineItem.laborAmount; this.pricingByDayUpchargeLineItem.laborAmount;
@ -678,9 +687,9 @@ export default {
handleDateClicked(date) { handleDateClicked(date) {
// do something to mark this as upcharge day or not... // do something to mark this as upcharge day or not...
if (date.isPricingByDayUpchargeDay) { if (date.isPricingByDayUpchargeDay) {
this.includePricingByDaySurcharge = true; this.includePricingByDayUpcharge = true;
} else { } else {
this.includePricingByDaySurcharge = false; this.includePricingByDayUpcharge = false;
} }
this.openInshopTimeSlotsModal(); this.openInshopTimeSlotsModal();

View file

@ -1749,11 +1749,11 @@ export const actions = {
pageNameToLog: pageNameToLog, pageNameToLog: pageNameToLog,
}); });
}, },
async getPricingByDayUpchargePart(context, { pageNameToLog }) { async getPricingByDayPart(context, { pageNameToLog }) {
return await globalMethods return await globalMethods
.callHttpClient({ .callHttpClient({
method: endpoints.GetPricingByDayUpchargePart.method, method: endpoints.GetPricingByDayPart.method,
endpoint: endpoints.GetPricingByDayUpchargePart.url, endpoint: endpoints.GetPricingByDayPart.url,
logApiCall: true, logApiCall: true,
pageNameToLog: pageNameToLog, pageNameToLog: pageNameToLog,
}) })