item.partType == PRICING_BY_DAY_UPCHARGE_FEE_PART_TYPE
+ );
+ if (pricingByDayUpchargeFeeIndex > -1) {
+ includePricingByDaySurcharge = true;
+ }
+ }
+
+ // Load page with date already selected?
let preSelectedDate = await store.getters.order.schedule.date;
if (!preSelectedDate || preSelectedDate.startTime === null) {
preSelectedDate = null;
}
- const datePickerInitialDataPromise = await datePicker.methods.loadInitialData({
- // setup config options for date-picker
- selectableDatesSetting: "custom",
- initialViewRowsToShow: 5,
- customSelectableDatesCallback: getAvailableDates,
- preSelectedDate: preSelectedDate,
- });
- // TODO - ONCE A DATEPICKER VERSION IS FINALIZED,
- // MAKE SURE THE ABOVE METHOD loadInitialData POINTS TO THE RIGHT FILE
+ // Set up promises
+ const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
+
+ const alertReasonsPromise = locationAlerts.methods.loadInitialData(
+ store.getters.order.serviceLocation.zipCodeCtu,
+ store.getters.order.serviceLocation.provider?.address?.zipCodeCtu
+ );
+
+ // While Pricing By Day Experiment is ongoing, using the updated datePicker
+ const datePickerInitialDataPromise =
+ await datePickerForPricingByDay.methods.loadInitialData({
+ // setup config options for date-picker
+ selectableDatesSetting: "custom",
+ initialViewRowsToShow: 5,
+ customSelectableDatesCallback: getAvailableDates,
+ preSelectedDate: preSelectedDate,
+ baseDayPrice: baseDayPrice,
+ pricingByDayUpcharge: pricingByDayUpcharge,
+ });
const premiumFeePromise = baseMixin.methods.dispatchStoreActionWithLogging(
storeActions.GET_MOBILE_PREMIUM_FEE,
null,
"schedule"
);
-
const premiumFeeWithPricePromise = premiumFeePromise.then((result) => {
if (result.data) {
return baseMixin.methods.dispatchStoreActionWithLogging(
@@ -264,11 +324,6 @@ export default {
}
});
- const alertReasonsPromise = locationAlerts.methods.loadInitialData(
- store.getters.order.serviceLocation.zipCodeCtu,
- store.getters.order.serviceLocation.provider?.address?.zipCodeCtu
- );
-
// Settle promises and get results
const promiseResultMap = [
{
@@ -302,6 +357,12 @@ export default {
: null;
vm.updateFooterButtonText(vm.selectedTimeSlotInfo);
vm.setDisplayWaitList();
+ vm.pricingByDayUpchargeLineItem = pricingByDayUpchargeLineItem;
+ vm.includePricingByDaySurcharge = includePricingByDaySurcharge;
+ vm.isPricingByDayExperiment = isPricingByDayExperiment;
+ vm.baseDayPrice = baseDayPrice;
+ vm.pricingByDayUpcharge = pricingByDayUpcharge;
+ vm.showPricingByDay = showPricingByDay;
});
},
computed: {
@@ -324,13 +385,6 @@ export default {
(selectableDate) => selectableDate.date === this.selectedDate
);
},
- isPricingByDayExperiment() {
- return (
- experimentMixin.methods
- .getSettingValue(experimentSettings.PRICING_BY_DAY)
- ?.toLowerCase() === "true"
- );
- },
},
methods: {
splitCopyOnCMSPlaceHolder,
@@ -377,6 +431,7 @@ export default {
this.appointmentType,
this.$store.getters.order.serviceLocation.provider.providerNumber
);
+
// ADD API CALL RESULTS TO EXISTING DATE DATA
this.selectableDatesData.days = this.selectableDatesData.days.concat(
newShopTimeSlots.days
@@ -512,11 +567,13 @@ export default {
false
);
- this.dispatchStoreAction(
- this.storeActions.SAVE_WAITLIST_REQUESTED,
- this.waitListRequested,
- false
- );
+ if (this.waitListRequested !== null && this.waitListRequested !== undefined) {
+ this.dispatchStoreAction(
+ this.storeActions.SAVE_WAITLIST_REQUESTED,
+ this.waitListRequested,
+ false
+ );
+ }
this.$router.navigateWithSaving(this.navigationScenarios.CLICKED_FORWARD, this.$route);
},
@@ -553,6 +610,28 @@ export default {
updateSupportingItems() {
const supportingItems = this.getSupportingItems();
+ // 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
+ );
+
+ if (this.includePricingByDaySurcharge) {
+ if (pricingByDayUpchargeFeeIndex > -1) {
+ supportingItems[pricingByDayUpchargeFeeIndex].laborAmount =
+ this.pricingByDayUpchargeLineItem.laborAmount;
+ supportingItems[pricingByDayUpchargeFeeIndex].sellingPrice =
+ this.pricingByDayUpchargeLineItem.sellingPrice;
+ supportingItems[pricingByDayUpchargeFeeIndex].kitPrice =
+ this.pricingByDayUpchargeLineItem.kitPrice;
+ } else {
+ supportingItems.push(this.pricingByDayUpchargeLineItem);
+ }
+ } else {
+ if (pricingByDayUpchargeFeeIndex >= 0) {
+ supportingItems.splice(pricingByDayUpchargeFeeIndex, 1);
+ }
+ }
+
// if we have a premium fee(early bird), then save/update supporting items
if (
this.appointmentType === AppointmentTypeStrings.MOBILE &&
@@ -562,7 +641,7 @@ export default {
(item) => item.partType == PREMIUM_FEE_PART_TYPE
);
- if (premiumFeeIndex >= 0) {
+ if (premiumFeeIndex > -1) {
supportingItems[premiumFeeIndex].laborAmount =
this.mobilePremiumAppointmentFee.laborAmount;
supportingItems[premiumFeeIndex].sellingPrice =
@@ -572,12 +651,6 @@ export default {
} else {
supportingItems.push(this.mobilePremiumAppointmentFee);
}
-
- this.dispatchStoreAction(
- this.storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING,
- supportingItems,
- false
- );
} else {
if (!supportingItems) {
return;
@@ -590,17 +663,28 @@ export default {
if (removePremiumFeeIndex >= 0) {
supportingItems.splice(removePremiumFeeIndex, 1);
- this.dispatchStoreAction(
- this.storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING,
- supportingItems,
- false
- );
}
}
+
+ this.dispatchStoreAction(
+ this.storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING,
+ supportingItems,
+ false
+ );
},
handleWaitListRequested(value) {
this.waitListRequested = value;
},
+ handleDateClicked(date) {
+ // do something to mark this as upcharge day or not...
+ if (date.isPricingByDayUpchargeDay) {
+ this.includePricingByDaySurcharge = true;
+ } else {
+ this.includePricingByDaySurcharge = false;
+ }
+
+ this.openInshopTimeSlotsModal();
+ },
},
watch: {
selectedDate(newValue, oldValue) {
@@ -629,7 +713,6 @@ export default {
funnelSubHeader,
Form,
loadingModal,
- datePicker,
datePickerForPricingByDay,
locationAlerts,
timeSlotModalQuestion,
diff --git a/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue b/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue
index 40c3926ba..82e11ea41 100644
--- a/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue
+++ b/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue
@@ -39,6 +39,13 @@
v-model="waitListRequested"
@click="waitListChecked" />
+
+
![]()
+
+
{
+ this.scrollToSuccessMessage();
+ });
+ }
+ },
modelValue: {
handler(newValue) {
this.handleChange(newValue);
@@ -583,10 +609,37 @@ export default {
margin-bottom: -8px;
.ui-checkbox {
padding-left: 0px;
+ input {
+ border-radius: 4px;
+ box-shadow: 0px 1px 4px 0px #00000033;
+ }
}
.form-check-input {
margin-left: 0px;
}
}
+ .waitlist-success {
+ background-color: #ecf5e9;
+ display: flex;
+ align-items: flex-start;
+ border: 1px solid #0c7e47;
+ border-radius: 5px;
+ font-size: $h5-font-size;
+ padding: 12px 16px;
+ margin-bottom: -8px;
+ .success-text {
+ margin-left: 8px;
+ strong {
+ font-weight: 600;
+ letter-spacing: 0%;
+ }
+ }
+ .success-image {
+ margin-top: 4.5px;
+ width: 16px;
+ height: 16px;
+ color: #0c7e47;
+ }
+ }
}
diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js
index 1983933ea..6fd6075ab 100644
--- a/src/mixins/base-mixin.js
+++ b/src/mixins/base-mixin.js
@@ -110,6 +110,25 @@ export default {
});
return filteredLineItems;
},
+ filterOutCertainPartTypesOrNumbers(
+ lineItemsArray,
+ { partTypesToRemove = [], partNumbersToRemove = [] }
+ ) {
+ // lineItems s/b an ARRAY here
+ if (!Array.isArray(lineItemsArray)) return;
+
+ partTypesToRemove.forEach((partType) => {
+ lineItemsArray = lineItemsArray.filter((item) => {
+ return !item?.partType?.includes(partType);
+ });
+ });
+ partNumbersToRemove.forEach((partNumber) => {
+ lineItemsArray = lineItemsArray.filter((item) => {
+ return !item?.partNumber?.includes(partNumber);
+ });
+ });
+ return lineItemsArray;
+ },
filterOutServicePackageDiscountPart(lineItems) {
const filteredLineItems = lineItems?.filter((item) => {
return !item?.partType?.includes(partTypeStrings.SERVICE_PACKAGE_DISCOUNT);
@@ -133,75 +152,18 @@ export default {
return totalPrice;
},
getTotalLineItemPrice(lineItem, includeTax) {
+ const kitPrice = lineItem.kitPrice ?? 0;
+ const laborAmount = lineItem.laborAmount ?? 0;
+ const sellingPrice = lineItem.sellingPrice ?? 0;
+ const salesTax = lineItem.salesTax ?? 0;
+
if (includeTax) {
- return (
- lineItem.kitPrice +
- lineItem.laborAmount +
- lineItem.sellingPrice +
- lineItem.salesTax
- );
+ return kitPrice + laborAmount + sellingPrice + salesTax;
} else {
- return lineItem.kitPrice + lineItem.laborAmount + lineItem.sellingPrice;
+ return kitPrice + laborAmount + sellingPrice;
}
},
- getDisplayAmountDue(lineItems) {
- return this.getAmountDue(lineItems).toLocaleString("en-US", {
- style: "currency",
- currency: "USD",
- });
- },
- getAmountDue(lineItems, includeTax = true) {
- var amountDue = 0;
- if (lineItems?.glassParts) {
- amountDue += this.getTotalPriceOfAllLineItemsAndChildParts(
- lineItems.glassParts,
- includeTax
- );
- }
- if (lineItems?.supportingItems) {
- amountDue += this.getTotalPriceOfAllLineItemsAndChildParts(
- lineItems.supportingItems,
- includeTax
- );
- }
-
- const order = this.hasSubmittedOrder() ? this.getSubmittedOrder() : store.getters.order;
- if (
- store.getters.coverageIsVerified &&
- !order.policy.isNoComp &&
- !order.policy.isItac
- ) {
- amountDue = order.policy.currentDeductible;
- }
-
- if (lineItems?.vaps) {
- amountDue += this.getTotalPriceOfAllLineItemsAndChildParts(
- lineItems.vaps,
- includeTax
- );
- }
-
- if (lineItems?.promos) {
- amountDue += this.getTotalPriceOfAllLineItemsAndChildParts(
- lineItems.promos,
- includeTax
- );
- }
-
- return ((amountDue * 100) / 100).toFixed(2);
- },
- getSubTotal(lineItems) {
- // this is amountDue without sales tax
- return this.getAmountDue(lineItems, false);
- },
- getSalesTax(lineItems) {
- // this is amountDue minus subTotal
- return (
- ((this.getAmountDue(lineItems) - this.getSubTotal(lineItems)) * 100) /
- 100
- ).toFixed(2);
- },
scrollToPageTop() {
const container = document.getElementsByClassName("page-container-grouped-styles")[0];
container.scrollTo({ top: 0, left: 0, behavior: "smooth" });
diff --git a/src/mixins/base-mixin.spec.js b/src/mixins/base-mixin.spec.js
index a3493910e..2484c0871 100644
--- a/src/mixins/base-mixin.spec.js
+++ b/src/mixins/base-mixin.spec.js
@@ -144,180 +144,6 @@ describe("baseMixin.js", () => {
expect(mixIn.methods.dispatchStoreActionWithLogging).toBeCalled();
});
-
- test("getAmountDue for verified deductible should be deductible plus any lineitems", () => {
- const mixIn = getMixInInstance({});
- const lineItems = {
- glassParts: [],
- supportingItems: [],
- vaps: [
- {
- cartItemType: "FRONT WIPERS",
- description: 'WIPER BLADE STANDARD 18"',
- kitPrice: 0,
- laborAmount: 0,
- partNumber: "WB18",
- partType: "FRONT WIPER",
- salesTax: 2.0,
- sellingPrice: 30.0,
- },
- {
- cartItemType: "FRONT WIPERS",
- description: 'WIPER BLADE STANDARD 26"',
- kitPrice: 0,
- laborAmount: 0,
- partNumber: "WB26",
- partType: "FRONT WIPER",
- salesTax: 1.0,
- sellingPrice: 20.0,
- },
- ],
- promos: [],
- };
-
- const payment = { insuranceCoverage: { isVerified: false } };
- const policy = { isNoComp: false, isItac: false, currentDeductible: 250 };
-
- store.getters = {
- payment: payment,
- policy: policy,
- order: {
- payment: payment,
- policy: policy,
- },
- hasSubmittedOrder: false,
- };
-
- var amtDue = mixIn.methods.getAmountDue(lineItems);
-
- expect(amtDue).toEqual("53.00");
- });
-
- test("getAmountDue should function with a submitted order", () => {
- const mixIn = getMixInInstance({});
- const lineItems = {
- glassParts: [],
- supportingItems: [],
- vaps: [
- {
- cartItemType: "FRONT WIPERS",
- description: 'WIPER BLADE STANDARD 18"',
- kitPrice: 0,
- laborAmount: 0,
- partNumber: "WB18",
- partType: "FRONT WIPER",
- salesTax: 2.0,
- sellingPrice: 30.0,
- },
- {
- cartItemType: "FRONT WIPERS",
- description: 'WIPER BLADE STANDARD 26"',
- kitPrice: 0,
- laborAmount: 0,
- partNumber: "WB26",
- partType: "FRONT WIPER",
- salesTax: 1.0,
- sellingPrice: 20.0,
- },
- ],
- promos: [],
- };
-
- const payment = { insuranceCoverage: { isVerified: false } };
- const policy = { isNoComp: false, isItac: false, currentDeductible: 250 };
-
- mixIn.methods.hasSubmittedOrder = jest.fn().mockReturnValue(true);
- mixIn.methods.getSubmittedOrder = jest.fn().mockReturnValue({
- payment: payment,
- policy: policy,
- });
-
- store.getters = {
- payment: {},
- policy: {},
- order: {},
- };
-
- var amtDue = mixIn.methods.getAmountDue(lineItems);
-
- expect(amtDue).toEqual("53.00");
- });
-
- test("getAmountDue for cash should sum lineitems", () => {
- const mixIn = getMixInInstance({});
- const lineItems = {
- glassParts: [
- {
- partNumber: "FW06143GTYN",
- description:
- "solar, heads-up display, third visor frit, soundproofing, rain/light sensor, lane departure warning system",
- color: "Green Tint",
- partType: "WINDSHIELD",
- canSafeliteRecalibrate: true,
- requiresRecalibration: true,
- requiresCapabilityQuestions: false,
- recalibrationType: "STATIC",
- childParts: [
- {
- partNumber: "RS 101 PAD",
- kitPrice: 0,
- laborAmount: 0,
- salesTax: 5.0,
- sellingPrice: 5.0,
- },
- ],
- id: "73e80976-79be-455a-b4e7-f9b058b61749",
- kitPrice: 0,
- laborAmount: 60,
- salesTax: 20.0,
- sellingPrice: 1000.0,
- },
- ],
- supportingItems: [],
- vaps: [
- {
- cartItemType: "FRONT WIPERS",
- description: 'WIPER BLADE STANDARD 18"',
- kitPrice: 0,
- laborAmount: 0,
- partNumber: "WB18",
- partType: "FRONT WIPER",
- salesTax: 2.0,
- sellingPrice: 30.0,
- },
- {
- cartItemType: "FRONT WIPERS",
- description: 'WIPER BLADE STANDARD 26"',
- kitPrice: 0,
- laborAmount: 0,
- partNumber: "WB26",
- partType: "FRONT WIPER",
- salesTax: 1.0,
- sellingPrice: 20.0,
- },
- ],
- promos: [],
- };
-
- const payment = { isInsurance: null, insuranceCoverage: { isVerified: null } };
- const policy = { isNoComp: false, isItac: false, currentDeductible: 0 };
-
- mixIn.methods.hasSubmittedOrder = jest.fn().mockReturnValue(false);
-
- store.getters = {
- payment: payment,
- policy: policy,
- order: {
- payment: payment,
- policy: policy,
- },
- hasSubmittedOrder: false,
- };
-
- var amtDue = mixIn.methods.getAmountDue(lineItems);
-
- expect(amtDue).toEqual("1143.00");
- });
});
function getMixInInstance({ isDispatchSuccess = true }) {
diff --git a/src/store/index.js b/src/store/index.js
index a7e7c6ae9..1a0a18d7a 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -1749,6 +1749,18 @@ export const actions = {
pageNameToLog: pageNameToLog,
});
},
+ async getPricingByDayUpchargePart(context, { pageNameToLog }) {
+ return await globalMethods
+ .callHttpClient({
+ method: endpoints.GetPricingByDayUpchargePart.method,
+ endpoint: endpoints.GetPricingByDayUpchargePart.url,
+ logApiCall: true,
+ pageNameToLog: pageNameToLog,
+ })
+ .then((response) => {
+ return response;
+ });
+ },
getServicePackageDiscountPart(context, { pageNameToLog }) {
const damage = context.getters.damage;
const damageType = damage.isRepair ? "Repair" : "Replace";