CASH-152: massive commit to implement pricing by day on schedule page

This commit is contained in:
Adam Caouette 2025-03-17 10:07:29 -04:00
parent 2bd4d42f57
commit 5412156766
15 changed files with 327 additions and 98 deletions

View file

@ -3,6 +3,8 @@ const partNumberStrings = {
MOBILE_STATIC_RECAL_FEE: "RECAL MOBILE",
MOBILE_DUAL_RECAL_FEE: "RECAL MOBILEDUAL",
DONATION: "DONATION",
// Fees
RECYCLE_FEE: "RECYCLE FEE",
};
export { partNumberStrings };

View file

@ -8,9 +8,17 @@ const PREMIUM_TIME_SLOT_ID_FLAG = "-PREMIUM";
const PREMIUM_FEE_PART_TYPE = "EARLY BIRD";
const PRICING_BY_DAY_UPCHARGE_FEE_PART_TYPE = "DISC CASHSAVE20";
const RouteCodeFlags = {
ALL_DAY_DROP_OFF: "ALL DAY DROP OFF",
OVERNIGHT_DROP_OFF: "OVERNIGHT DROP OFF",
};
export { AppointmentTypeStrings, PREMIUM_TIME_SLOT_ID_FLAG, PREMIUM_FEE_PART_TYPE, RouteCodeFlags };
export {
AppointmentTypeStrings,
PREMIUM_TIME_SLOT_ID_FLAG,
PREMIUM_FEE_PART_TYPE,
PRICING_BY_DAY_UPCHARGE_FEE_PART_TYPE,
RouteCodeFlags,
};

View file

@ -30,6 +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_SERVICE_PACKAGE_DISCOUNT_PART: "getServicePackageDiscountPart",
GET_SERVICEABILITY_DETAILS: "getServiceabilityDetails",
GET_SHOP_TIME_SLOTS: "getShopTimeSlots",

View file

@ -23,4 +23,6 @@ const MONTHS_OF_YEAR = [
const DAYS_OF_WEEK = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
export { TIMINGFUNC_MAP, BUFFER_OFFSET, MONTHS_OF_YEAR, DAYS_OF_WEEK };
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 };

View file

@ -66,15 +66,15 @@
type="radio"
name="day-of-month"
v-model="selectedDate"
@click="fireDateSelectedEvent"
@keypress.enter="fireDateSelectedEvent"
@click="fireDateSelectedEvent($event, date)"
@keypress.enter="fireDateSelectedEvent($event, date)"
:value="date.inputValue"
:id="`${month.monthLabel}-${date.dateNum.toString()}`" />
<label :for="`${month.monthLabel}-${date.dateNum.toString()}`">
<span>{{ date.dateNum.toString() }}</span>
<span v-if="showPricingByDay">$000</span>
<span v-if="showPricingByDay && date.isSelectable">
{{ date.priceString }}
</span>
</label>
</div>
</div>
@ -106,6 +106,7 @@ import {
TIMINGFUNC_MAP,
BUFFER_OFFSET,
MONTHS_OF_YEAR,
PREMIUM_DAY_INDEXES,
} from "@/digital-components/date-picker/mixins/constants";
import {
selectableDaysOptions,
@ -160,6 +161,8 @@ export default {
default: "",
},
showPricingByDay: Boolean,
baseDayPrice: Number,
pricingByDayUpcharge: Number,
},
setup(props) {
const uuid = uuidv4();
@ -224,17 +227,12 @@ export default {
initializeComponent(initialData) {
this.setCalendarData(initialData);
},
fireDateSelectedEvent(event) {
fireDateSelectedEvent(event, date) {
// Ignore if arrow key selected radioButton
if (event.screenX === 0 && event.screenY === 0) {
return;
}
this.$emit("date-clicked");
},
fireDateSelectedEvent2(date) {
console.log("date: ", date);
this.selectedDate = date;
this.$emit("date-clicked");
this.$emit("date-clicked", date);
},
getWeekStartDate(dateString) {
const date = convertDateStringToDate(dateString);
@ -433,6 +431,8 @@ export default {
hideSomeDaysForInitialView: hideSomeDaysForInitialView,
hideSecondMonth: hideSecondMonth,
preSelectedDate: config.preSelectedDate,
baseDayPrice: config.baseDayPrice,
pricingByDayUpcharge: config.pricingByDayUpcharge,
};
return initialData;
});
@ -457,6 +457,8 @@ export default {
initialViewEndDate: config.initialViewEndDate,
hideSecondMonth: hideSecondMonth,
preSelectedDate: config.preSelectedDate,
baseDayPrice: config.baseDayPrice,
pricingByDayUpcharge: config.pricingByDayUpcharge,
};
if (direction === "future") {
// first 0, then 1
@ -590,6 +592,17 @@ export default {
("0" + monthNum).slice(-2) +
"-" +
("0" + i).slice(-2);
const dayIndex = convertDateStringToDate(dateString).getDay();
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 priceString = "$" + displayPrice;
if (offset === 0 && i === this.todayDateNum) {
dayClasses += " current-day";
@ -600,7 +613,7 @@ export default {
if (offset === 0 && i > this.todayDateNum && calendarViewDirection === "past") {
dayClasses += " unavailable-day";
}
if (convertDateStringToDate(dateString).getDay() === 0) {
if (dayIndex === 0) {
dayClasses += " sunday";
}
if (
@ -615,10 +628,9 @@ export default {
dateNum: i,
dayClasses: dayClasses,
inputValue: dateString,
isSelectable:
this.selectableDatesData.findIndex((date) => date.date === dateString) > -1
? true
: false,
priceString: priceString,
isSelectable: isSelectable,
isPricingByDayUpchargeDay: isPricingByDayUpchargeDay,
};
dates.push(dateObject);
}

View file

@ -1,4 +1,5 @@
import store from "@/store";
import { storeActions } from "@/constants/store-actions";
import baseMixin from "@/mixins/base-mixin.js";
export function getDisplayAmountDue(lineItemsObject, includeTax = true) {
@ -58,3 +59,33 @@ export function getSalesTax(lineItemsObject) {
// this is amountDue minus subTotal
return (((getAmountDue(lineItemsObject) - getSubTotal(lineItemsObject)) * 100) / 100).toFixed(2);
}
export async function getPriceUpchargeByDayPart(pageNameToLog) {
// Get the Pricing By Day Part
const basePriceByDayPart = await baseMixin.methods.dispatchStoreActionWithLogging(
storeActions.GET_PRICING_BY_DAY_UPCHARGE_PART,
null,
pageNameToLog,
false
);
if (
basePriceByDayPart?.data === null ||
basePriceByDayPart?.data === undefined ||
basePriceByDayPart?.data === ""
) {
return null;
}
// Get the Pricing By Day Base Part price
const pricingResults = await baseMixin.methods.dispatchStoreActionWithLogging(
storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
{
availableLineItems: [basePriceByDayPart?.data],
},
pageNameToLog,
false
);
return pricingResults[0];
}

View file

@ -3,7 +3,7 @@ import {
getAmountDue,
getSubTotal,
getSalesTax,
} from "@/helpers/cart-and-payment-helper.js";
} from "@/helpers/pricing-helper.js";
const lineItems = {
glassParts: [],
@ -33,7 +33,7 @@ const lineItems = {
promos: [],
};
describe("cart-and-payment-helper", () => {
describe("pricing-helper", () => {
describe("getDisplayAmountDue", () => {
it("should return the correct display amount due", () => {
const result = getDisplayAmountDue(lineItems);

View file

@ -1,6 +1,12 @@
import { partTypeStrings } from "@/constants/part-type-strings";
import { damageLocationsSelected as glassLocations } from "@/constants/damage-locations-selected";
import { packageNames } from "@/constants/package-names";
import baseMixin from "@/mixins/base-mixin.js";
import { getItemsWithoutRecalParts } from "@/helpers/recal-helper";
import {
getPromosThatMatchLineItemsOnOrder,
removeVapsPromosFromPromoArray,
} from "@/helpers/promotions-helper";
export function containsLineItemWithPartType(typeToFind, itemsToSearch) {
const partTypeMatches = findLineItemsWithPartType(typeToFind, itemsToSearch);
@ -248,6 +254,90 @@ export function getDiscountedPackageName(discountPackage) {
return package_names[discountPackage] || null;
}
// export function getDiscountedPackagePriceString2(packageName, servicePackageDiscount) {
// const formattedPriceFloat = parseFloat(
// this.getPackagePrice(packageName, {
// discountedPrice: true,
// servicePackageDiscount,
// })
// ).toFixed(2);
// return "$" + formattedPriceFloat;
// }
// export function getPackagePrice(
// packageName,
// { discountedPrice = false, servicePackageDiscount = false }
// ) {
// let lineItemsToPrice = [...this.shallowLineItems];
// if (this.isRecalibrationOnOrder && this.shouldHideRecalibration) {
// lineItemsToPrice = getItemsWithoutRecalParts(lineItemsToPrice);
// }
// //remove service package discount part
// if (this.isServicePackageDiscountOnOrder) {
// lineItemsToPrice = lineItemsToPrice.filter((item) => {
// return item.partType != this.servicePackageDiscountParts[0].partType;
// });
// }
// if (discountedPrice) {
// lineItemsToPrice.push(...removeVapsPromosFromPromoArray(this.activePromos));
// }
// if (servicePackageDiscount) {
// lineItemsToPrice.push(...this.servicePackageDiscountParts);
// }
// let priceFloat = baseMixin.methods.getTierOnePackagePrice(
// baseMixin.methods.filterOutFees(lineItemsToPrice)
// );
// priceFloat += this.getVapsPrice(packageName, discountedPrice);
// // console.log("SPHelper getPackagePrice()... priceFloat: ", priceFloat)
// // console.log(" ")
// return priceFloat;
// }
// export function getVapsPrice(packageName, applyPromoDiscounts = false) {
// const vapsItems = this.getVapsLineItemsForSelectedPackage(packageName);
// let price = 0;
// vapsItems.forEach((item) => {
// price += baseMixin.methods.getTotalLineItemPrice(item);
// });
// if (applyPromoDiscounts && this.activePromos) {
// const relevantPromos = getPromosThatMatchLineItemsOnOrder(this.lineItems.promos, vapsItems);
// relevantPromos.forEach((promo) => {
// price += baseMixin.methods.getTotalLineItemPrice(promo);
// });
// }
// return price;
// }
// export function getVapsLineItemsForSelectedPackage(packageName) {
// const packageContentTypes = getPackageContents(
// this.glassToReplace,
// this.shallowLineItems,
// this.isRepair,
// packageName
// );
// let vapsLineItemsForSelectedPackage = [];
// packageContentTypes.forEach((vapType) => {
// vapsLineItemsForSelectedPackage.push(
// ...findLineItemsWithPartType(vapType, this.shallowLineItems)
// );
// });
// return vapsLineItemsForSelectedPackage;
// }
function maxTier(tierA, tierB) {
if (tierA === packageNames.TIER_THREE || tierB === packageNames.TIER_THREE) {
return packageNames.TIER_THREE;

View file

@ -16,7 +16,7 @@ jest.mock("@/helpers/heritage-integration/order-helper.js", () => ({
submitWorkOrder: jest.fn(),
}));
jest.mock("@/helpers/cart-and-payment-helper.js", () => ({
jest.mock("@/helpers/pricing-helper.js", () => ({
getAmountDue: jest.fn(),
}));

View file

@ -8,7 +8,7 @@ import store from "@/store";
import { storeActions } from "@/constants/store-actions";
import { paymentMethods } from "@/constants/payment-method-constants";
jest.mock("@/helpers/cart-and-payment-helper.js", () => ({
jest.mock("@/helpers/pricing-helper.js", () => ({
getAmountDue: jest.fn(),
getDisplayAmountDue: jest.fn(),
}));

View file

@ -266,6 +266,7 @@ export default {
false
);
// This will remove any servicePackageDiscount item from lineItems.supportingItems
baseMixin.methods.dispatchStoreAction(
storeActions.SAVE_SUPPORTING_ITEMS,
resultMap.supportingItems,

View file

@ -130,6 +130,10 @@ jest.mock("@/mixins/base-mixin.js", () => ({
]);
}
}),
filterOutCertainPartTypesOrNumbers: jest.fn(),
hasSubmittedOrder: jest.fn(),
getTotalPriceOfAllLineItemsAndChildParts: jest.fn(),
getTotalLineItemPrice: jest.fn(),
},
}));

View file

@ -19,18 +19,20 @@
</template>
<locationAlerts cmsWidgetPrefix="LocationAlert-" ref="locationAlerts" />
<datePickerForPricingByDay
v-if="isPricingByDayExperiment"
v-show="isPricingByDayExperiment"
customComponentId="dateQuestion"
selectableDatesSetting="custom"
ref="datePicker"
ref="datePickerForPricingByDay"
v-model="selectedDate"
class="text-link-small"
:customSelectableDatesCallback="getAvailableDatesMethod"
validationRules="date-required"
:baseDayPrice="baseDayPrice"
:pricingByDayUpcharge="pricingByDayUpcharge"
:showPricingByDay="showPricingByDay"
@date-clicked="openInshopTimeSlotsModal" />
@date-clicked="handleDateClicked" />
<datePicker
v-else
v-show="!isPricingByDayExperiment"
customComponentId="dateQuestion"
selectableDatesSetting="custom"
ref="datePicker"
@ -104,13 +106,17 @@ import {
convertDateStringToDate,
sumDateString,
} from "@/layouts/schedule/helpers/schedule-helper";
import { AppointmentTypeStrings, PREMIUM_FEE_PART_TYPE } from "@/constants/schedule-constants";
import {
AppointmentTypeStrings,
PREMIUM_FEE_PART_TYPE,
PRICING_BY_DAY_UPCHARGE_FEE_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 { getDisplayAmountDue } from "@/helpers/pricing-helper.js";
import { getAmountDue, getPriceUpchargeByDayPart } from "@/helpers/pricing-helper.js";
import { getItemsWithoutRecalParts } from "@/helpers/recal-helper";
import { partNumberStrings } from "@/constants/part-number-strings";
import { deepClone } from "@/helpers/object-helper";
@ -228,32 +234,102 @@ export default {
mobilePremiumAppointmentFee: null,
waitListRequested: null,
displayWaitList: null,
pricingByDayUpchargeLineItem: null,
includePricingByDaySurcharge: null,
isPricingByDayExperiment: null,
baseDayPrice: null,
pricingByDayUpcharge: null,
showPricingByDay: null,
};
},
async beforeRouteEnter(to, from, next) {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
// Get data needed for Pricing By Day
const lineItems = deepClone(await store.getters.order.lineItems);
const isRecalibrationOnOrder = await store.getters.isRecalibrationOnOrder;
const shouldHideRecalibration =
experimentMixin.methods
.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE)
?.toLowerCase() === "true" && isRecalibrationOnOrder;
const glassParts =
isRecalibrationOnOrder && shouldHideRecalibration
? getItemsWithoutRecalParts(lineItems.glassParts)
: (lineItems.glassParts ?? []);
const supportingItemsWithoutFees = baseMixin.methods.filterOutCertainPartTypesOrNumbers(
lineItems.supportingItems,
{ partNumbersToRemove: [partNumberStrings.RECYCLE_FEE] }
);
const lineItemsToBePriced = {
glassParts: glassParts,
supportingItems: supportingItemsWithoutFees,
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 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
);
// Check to see if includePricingByDaySurcharge should already be set (based on order lineItems)
let includePricingByDaySurcharge = false;
if (supportingItemsWithoutFees) {
const pricingByDayUpchargeFeeIndex = supportingItemsWithoutFees.findIndex(
(item) => 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, there are two different datePickers, but only one will load
let datePickerInitialDataPromise;
if (isPricingByDayExperiment) {
datePickerInitialDataPromise = await datePickerForPricingByDay.methods.loadInitialData({
// setup config options for date-picker
selectableDatesSetting: "custom",
initialViewRowsToShow: 5,
customSelectableDatesCallback: getAvailableDates,
preSelectedDate: preSelectedDate,
baseDayPrice: baseDayPrice,
pricingByDayUpcharge: pricingByDayUpcharge,
});
} else {
datePickerInitialDataPromise = await datePicker.methods.loadInitialData({
// setup config options for date-picker
selectableDatesSetting: "custom",
initialViewRowsToShow: 5,
customSelectableDatesCallback: getAvailableDates,
preSelectedDate: preSelectedDate,
});
}
const premiumFeePromise = baseMixin.methods.dispatchStoreActionWithLogging(
storeActions.GET_MOBILE_PREMIUM_FEE,
null,
"schedule"
);
const premiumFeeWithPricePromise = premiumFeePromise.then((result) => {
if (result.data) {
return baseMixin.methods.dispatchStoreActionWithLogging(
@ -269,11 +345,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 = [
{
@ -300,6 +371,7 @@ export default {
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
vm.$refs.datePicker.initializeComponent(resultMap.datePickerInitialData);
vm.$refs.datePickerForPricingByDay.initializeComponent(resultMap.datePickerInitialData);
vm.$refs.locationAlerts.initializeComponent(resultMap.alertReasons);
vm.selectableDatesData = resultMap.datePickerInitialData.initialShopTimeSlotsResponse;
vm.mobilePremiumAppointmentFee = resultMap.premiumFeeWithPrice
@ -307,6 +379,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: {
@ -329,45 +407,6 @@ export default {
(selectableDate) => selectableDate.date === this.selectedDate
);
},
isPricingByDayExperiment() {
return (
experimentMixin.methods
.getSettingValue(experimentSettings.PRICING_BY_DAY)
?.toLowerCase() === "true"
);
},
showPricingByDay() {
return !this.$store.getters.payment.isInsurance && this.isPricingByDayExperiment;
},
lineItemsToBePriced() {
const lineItems = deepClone(store.getters.order.lineItems);
const glassParts = (this.isRecalibrationOnOrder && this.shouldHideRecalibration) ?
getItemsWithoutRecalParts(lineItems.glassParts) :
lineItems.glassParts ?? [];
const supportingItemsWithoutFees = baseMixin.methods.filterOutCertainPartTypesOrNumbers(lineItems.supportingItems, {partNumbersToRemove: [partNumberStrings.RECYCLE_FEE]});
return {
glassParts: glassParts,
supportingItems: supportingItemsWithoutFees,
vaps: lineItems.vaps ?? [],
promos: lineItems.promos ?? [],
};
},
lowestPrice() {
return getDisplayAmountDue(this.lineItemsToBePriced, false); // passing false here so IncludeTax is false
},
isRecalibrationOnOrder() {
return store.getters.isRecalibrationOnOrder;
},
shouldHideRecalibration() {
return (
experimentMixin.methods
.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE)
?.toLowerCase() === "true" && this.isRecalibrationOnOrder
);
},
},
methods: {
splitCopyOnCMSPlaceHolder,
@ -414,6 +453,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
@ -590,6 +630,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 &&
@ -599,7 +661,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 =
@ -609,12 +671,6 @@ export default {
} else {
supportingItems.push(this.mobilePremiumAppointmentFee);
}
this.dispatchStoreAction(
this.storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING,
supportingItems,
false
);
} else {
if (!supportingItems) {
return;
@ -627,17 +683,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) {

View file

@ -144,7 +144,6 @@ describe("baseMixin.js", () => {
expect(mixIn.methods.dispatchStoreActionWithLogging).toBeCalled();
});
});
function getMixInInstance({ isDispatchSuccess = true }) {

View file

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