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",
method: "GET",
},
GetPricingByDayUpchargePart: {
url: "/parts/api/v1/parts/get-pricing-by-day-part-number",
GetPricingByDayPart: {
url: "/parts/api/v1/parts/pricing-by-day-part-number",
method: "GET",
},
GetServicePackageDiscountPart: {

View file

@ -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,
};

View file

@ -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",

View file

@ -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 };

View file

@ -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 &&

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
const basePriceByDayPart = await baseMixin.methods.dispatchStoreActionWithLogging(
storeActions.GET_PRICING_BY_DAY_UPCHARGE_PART,
storeActions.GET_PRICING_BY_DAY_PART,
null,
pageNameToLog,
false

View file

@ -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();

View file

@ -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,
})