Merge pull request #2377 from Safelite/rlsmerge/2025.03.27-to-develop

release merge 2025.03.27 to develop
This commit is contained in:
scottkiener-at-safelite 2025-03-25 10:05:03 -04:00 committed by GitHub
commit ab750a4b30
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 90 additions and 49 deletions

View file

@ -5,6 +5,7 @@ const partNumberStrings = {
DONATION: "DONATION", DONATION: "DONATION",
// Fees // Fees
RECYCLE_FEE: "RECYCLE FEE", RECYCLE_FEE: "RECYCLE FEE",
PRICING_BY_DAY_UPCHARGE: "PREMAPPT GEN",
}; };
export { partNumberStrings }; export { partNumberStrings };

View file

@ -8,8 +8,7 @@ const PREMIUM_TIME_SLOT_ID_FLAG = "-PREMIUM";
const PREMIUM_FEE_PART_TYPE = "EARLY BIRD"; const PREMIUM_FEE_PART_TYPE = "EARLY BIRD";
// TODO; This will need updating with real PricingByDay part type const PRICING_BY_DAY_PART_TYPE = "PREMAPPT GEN";
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",

View file

@ -26,43 +26,36 @@ const DAYS_OF_WEEK = [
{ {
label: "Sunday", label: "Sunday",
cssClass: "sunday", cssClass: "sunday",
index: 0, isPricingByDayUpchargeDay: true,
isPricingByDayUpchargeDay: false,
}, },
{ {
label: "Monday", label: "Monday",
cssClass: "monday", cssClass: "monday",
index: 1,
isPricingByDayUpchargeDay: true, isPricingByDayUpchargeDay: true,
}, },
{ {
label: "Tuesday", label: "Tuesday",
cssClass: "tuesday", cssClass: "tuesday",
index: 2,
isPricingByDayUpchargeDay: false, isPricingByDayUpchargeDay: false,
}, },
{ {
label: "Wednesday", label: "Wednesday",
cssClass: "wednesday", cssClass: "wednesday",
index: 3,
isPricingByDayUpchargeDay: false, isPricingByDayUpchargeDay: false,
}, },
{ {
label: "Thursday", label: "Thursday",
cssClass: "thursday", cssClass: "thursday",
index: 4,
isPricingByDayUpchargeDay: false, isPricingByDayUpchargeDay: false,
}, },
{ {
label: "Friday", label: "Friday",
cssClass: "friday", cssClass: "friday",
index: 5,
isPricingByDayUpchargeDay: true, isPricingByDayUpchargeDay: true,
}, },
{ {
label: "Saturday", label: "Saturday",
cssClass: "saturday", cssClass: "saturday",
index: 6,
isPricingByDayUpchargeDay: true, isPricingByDayUpchargeDay: true,
}, },
]; ];

View file

@ -1,5 +1,7 @@
<template> <template>
<div class="date-picker text-center" :class="`${calendarViewDirection} ${isPricingByDayClass}`"> <div
class="date-picker text-center"
:class="`${calendarViewDirection} ${isPricingByDayClass} ${showPricingByDayClass}`">
<fieldset id="date-picker-fieldset" ref="datePickerFieldset"> <fieldset id="date-picker-fieldset" ref="datePickerFieldset">
<legend class="sr-only">Select a day and time</legend> <legend class="sr-only">Select a day and time</legend>
<div <div
@ -60,6 +62,7 @@
date.dateNum === 1 ? 'first-day-' + month.startDateDayIndex : '', date.dateNum === 1 ? 'first-day-' + month.startDateDayIndex : '',
date.dayClasses, date.dayClasses,
date.isSelectable ? 'selectable-day' : '', date.isSelectable ? 'selectable-day' : '',
date.isPricingByDayUpchargeDay ? 'upch-day' : '',
]"> ]">
<input <input
:disabled="!date.isSelectable" :disabled="!date.isSelectable"
@ -220,6 +223,9 @@ export default {
isPricingByDayClass() { isPricingByDayClass() {
return this.isPricingByDayExperiment ? "pricing-by-day" : ""; return this.isPricingByDayExperiment ? "pricing-by-day" : "";
}, },
showPricingByDayClass() {
return this.showPricingByDay ? "show-pricing-by-day" : "";
},
selectedDate: { selectedDate: {
get() { get() {
return this.modelValue; return this.modelValue;
@ -1143,8 +1149,8 @@ export default {
label { label {
background-color: $white; background-color: $white;
border: none; border: none;
min-width: initial; min-width: 100%;
width: initial; width: 100%;
height: -webkit-fill-available; height: -webkit-fill-available;
border-radius: 0; border-radius: 0;
cursor: pointer; cursor: pointer;
@ -1163,6 +1169,35 @@ export default {
} }
} }
} }
&.date-picker.show-pricing-by-day {
.radio-wrapper {
&.selectable-day label span {
text-decoration: none;
color: $gray-600;
font-weight: 400;
font-family: "AvertaSemibold";
&.price {
color: $green;
}
}
&.upch-day label span.price {
color: $gray-600;
font-weight: 400;
font-family: $font-family-sans-serif;
}
input[type="radio"] {
&:focus + label,
&:checked:focus + label {
color: $gray-600;
}
&:checked + label {
color: $blue;
}
}
}
}
} }
.btn-link { .btn-link {

View file

@ -54,7 +54,7 @@
:estimatedServiceMinutesMaximum=" :estimatedServiceMinutesMaximum="
selectableDatesData.estimatedServiceMinutesMaximum selectableDatesData.estimatedServiceMinutesMaximum
" "
@waitListRequested-emitted="handleWaitListRequested" @waitListRequested="handleWaitListRequested"
@time-slot-modal-closed="timeSlotModalClosed" @time-slot-modal-closed="timeSlotModalClosed"
validationRules="time-slot-selection-required" validationRules="time-slot-selection-required"
@TimeSlotSelected="forwardButtonAction" /> @TimeSlotSelected="forwardButtonAction" />
@ -250,9 +250,15 @@ export default {
isRecalibrationOnOrder && shouldHideRecalibration isRecalibrationOnOrder && shouldHideRecalibration
? getItemsWithoutRecalParts(lineItems.glassParts) ? getItemsWithoutRecalParts(lineItems.glassParts)
: (lineItems.glassParts ?? []); : (lineItems.glassParts ?? []);
const supportingItemsFromStore = lineItems?.supportingItems;
const supportingItemsWithoutFees = baseMixin.methods.filterOutCertainPartTypesOrNumbers( const supportingItemsWithoutFees = baseMixin.methods.filterOutCertainPartTypesOrNumbers(
lineItems.supportingItems, lineItems.supportingItems,
{ partNumbersToRemove: [partNumberStrings.RECYCLE_FEE] } {
partNumbersToRemove: [
partNumberStrings.RECYCLE_FEE,
partNumberStrings.PRICING_BY_DAY_UPCHARGE,
],
}
); );
const lineItemsToBePriced = { const lineItemsToBePriced = {
glassParts: glassParts, glassParts: glassParts,
@ -266,8 +272,8 @@ export default {
// Check to see if includePricingByDayUpcharge should already be set (based on order lineItems) // Check to see if includePricingByDayUpcharge should already be set (based on order lineItems)
let includePricingByDayUpcharge = false; let includePricingByDayUpcharge = false;
if (supportingItemsWithoutFees) { if (supportingItemsFromStore) {
const pricingByDayUpchargeFeeIndex = supportingItemsWithoutFees.findIndex( const pricingByDayUpchargeFeeIndex = supportingItemsFromStore?.findIndex(
(item) => item.partType == PRICING_BY_DAY_PART_TYPE (item) => item.partType == PRICING_BY_DAY_PART_TYPE
); );
if (pricingByDayUpchargeFeeIndex > -1) { if (pricingByDayUpchargeFeeIndex > -1) {
@ -300,7 +306,9 @@ export default {
}); });
// Get pricingByDayUpcharge needed for Pricing By Day // Get pricingByDayUpcharge needed for Pricing By Day
const pricingByDayUpchargePartPromise = getPricingByDayPartWithPrice(); const pricingByDayUpchargePartPromise = showPricingByDay
? getPricingByDayPartWithPrice()
: null;
const premiumFeePromise = baseMixin.methods.dispatchStoreActionWithLogging( const premiumFeePromise = baseMixin.methods.dispatchStoreActionWithLogging(
storeActions.GET_MOBILE_PREMIUM_FEE, storeActions.GET_MOBILE_PREMIUM_FEE,
@ -348,10 +356,12 @@ export default {
const resultMap = await settleAllPromises(promiseResultMap); const resultMap = await settleAllPromises(promiseResultMap);
const pricingByDayUpcharge = await baseMixin.methods.getTotalLineItemPrice( const pricingByDayUpcharge = showPricingByDay
resultMap.pricingByDayUpchargePart, ? await baseMixin.methods.getTotalLineItemPrice(
false resultMap.pricingByDayUpchargePart,
); false
)
: null;
const datePickerInitialData = resultMap.datePickerInitialData; const datePickerInitialData = resultMap.datePickerInitialData;
datePickerInitialData.pricingByDayBasePrice = pricingByDayBasePrice; datePickerInitialData.pricingByDayBasePrice = pricingByDayBasePrice;
@ -620,24 +630,26 @@ export default {
const supportingItems = this.getSupportingItems(); const supportingItems = this.getSupportingItems();
// 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( if (this.showPricingByDay) {
(item) => item.partType == PRICING_BY_DAY_PART_TYPE const pricingByDayUpchargeFeeIndex = supportingItems?.findIndex(
); (item) => item.partType == PRICING_BY_DAY_PART_TYPE
);
if (this.includePricingByDayUpcharge) { if (this.includePricingByDayUpcharge) {
if (pricingByDayUpchargeFeeIndex > -1) { if (pricingByDayUpchargeFeeIndex > -1) {
supportingItems[pricingByDayUpchargeFeeIndex].laborAmount = supportingItems[pricingByDayUpchargeFeeIndex].laborAmount =
this.pricingByDayUpchargeLineItem.laborAmount; this.pricingByDayUpchargeLineItem.laborAmount;
supportingItems[pricingByDayUpchargeFeeIndex].sellingPrice = supportingItems[pricingByDayUpchargeFeeIndex].sellingPrice =
this.pricingByDayUpchargeLineItem.sellingPrice; this.pricingByDayUpchargeLineItem.sellingPrice;
supportingItems[pricingByDayUpchargeFeeIndex].kitPrice = supportingItems[pricingByDayUpchargeFeeIndex].kitPrice =
this.pricingByDayUpchargeLineItem.kitPrice; this.pricingByDayUpchargeLineItem.kitPrice;
} else {
supportingItems.push(this.pricingByDayUpchargeLineItem);
}
} else { } else {
supportingItems.push(this.pricingByDayUpchargeLineItem); if (pricingByDayUpchargeFeeIndex >= 0) {
} supportingItems.splice(pricingByDayUpchargeFeeIndex, 1);
} else { }
if (pricingByDayUpchargeFeeIndex >= 0) {
supportingItems.splice(pricingByDayUpchargeFeeIndex, 1);
} }
} }

View file

@ -43,8 +43,8 @@
v-if="waitListRequested" v-if="waitListRequested"
class="mt-5 rounded waitlist-success" class="mt-5 rounded waitlist-success"
ref="waitlistSuccessMessage"> ref="waitlistSuccessMessage">
<img :src="WaitListSuccessImage" class="success-image" /> <img :src="waitListSuccessImage" class="success-image" />
<span v-html="WaitListSuccessText" class="success-text"></span> <span v-html="waitListSuccessText" class="success-text"></span>
</div> </div>
<div <div
class="mt-5 mb-2 supplemental-information" class="mt-5 mb-2 supplemental-information"
@ -366,10 +366,10 @@ export default {
displayWaitListFeature() { displayWaitListFeature() {
return this.displayWaitList; return this.displayWaitList;
}, },
WaitListSuccessImage() { waitListSuccessImage() {
return this.getCmsContent("WaitListSuccessWidget", "Image"); return this.getCmsContent("WaitListSuccessWidget", "Image");
}, },
WaitListSuccessText() { waitListSuccessText() {
return this.getCmsContent("WaitListSuccessWidget", "BodyText"); return this.getCmsContent("WaitListSuccessWidget", "BodyText");
}, },
}, },
@ -539,7 +539,7 @@ export default {
}; };
}, },
waitListChecked(event) { waitListChecked(event) {
this.$emit("waitListRequested-emitted", event.target.checked); this.$emit("waitListRequested", event.target.checked);
}, },
scrollToSuccessMessage() { scrollToSuccessMessage() {
const successMessageElement = this.$refs.waitlistSuccessMessage; const successMessageElement = this.$refs.waitlistSuccessMessage;
@ -625,10 +625,10 @@ export default {
border: 1px solid #0c7e47; border: 1px solid #0c7e47;
border-radius: 5px; border-radius: 5px;
font-size: $h5-font-size; font-size: $h5-font-size;
padding: 12px 16px; padding: 0.75rem 1rem;
margin-bottom: -8px; margin-bottom: -0.5rem;
.success-text { .success-text {
margin-left: 8px; margin-left: 0.5rem;
strong { strong {
font-weight: 600; font-weight: 600;
letter-spacing: 0%; letter-spacing: 0%;
@ -636,8 +636,8 @@ export default {
} }
.success-image { .success-image {
margin-top: 4.5px; margin-top: 4.5px;
width: 16px; width: 1rem;
height: 16px; height: 1rem;
color: #0c7e47; color: #0c7e47;
} }
} }

View file

@ -720,7 +720,8 @@ export const mutations = {
// if we're loading a session and we do not have a provider number yet, then set isInsurance to null so that // if we're loading a session and we do not have a provider number yet, then set isInsurance to null so that
// a service package is not selected by default on the quote page. // a service package is not selected by default on the quote page.
if ( if (
!sessionInformation.order.payment.isInsurance && (sessionInformation.order.payment.isInsurance === null ||
sessionInformation.order.payment.isInsurance === undefined) &&
!sessionInformation.order.serviceLocation.provider?.providerNumber !sessionInformation.order.serviceLocation.provider?.providerNumber
) { ) {
state.order.payment.isInsurance = null; state.order.payment.isInsurance = null;