Merge pull request #2933 from Safelite/feature/CASH-1620-temp-revert

Revert "Merge pull request #2930 from Safelite/feature/CASH-1620"
This commit is contained in:
chloeherdsafelite 2025-11-05 14:14:47 -05:00 committed by GitHub
commit cc09011504
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 197 additions and 260 deletions

View file

@ -3,7 +3,7 @@ const cartItemCategories = {
GLASS_PARTS: "glassParts",
SUPPORTING_ITEMS: "supportingItems",
PROMOS: "promos",
QUOTE_PAGE_DISCOUNT: "quotePageDiscount",
SERVICE_PACKAGE_DISCOUNT: "servicePackageDiscount",
};
export { cartItemCategories };

View file

@ -10,7 +10,7 @@ const cartItemTypes = {
PROMOS: "PROMOS",
EARLY_BIRD: "EARLY BIRD",
SUPPLIES_REPAIR: "SUPPLIES-REPAIR",
QUOTE_PAGE_DISCOUNT: "QUOTE PAGE DISCOUNT",
SERVICE_PACKAGE_DISCOUNT: "SERVICE PACKAGE DISCOUNT",
DONATION: "DONATION",
};

View file

@ -10,7 +10,6 @@ const partTypeStrings = {
REPAIR_FEE: "REPAIR FEE",
EARLY_BIRD: "EARLY BIRD",
SERVICE_PACKAGE_DISCOUNT: "SERVICE PACKAGE DISCOUNT",
QUOTE_PAGE_DISCOUNT: "QUOTE PAGE DISCOUNT",
DONATION: "DONATION",
};

View file

@ -1,80 +0,0 @@
import { packageNames } from "./package-names";
import { partTypeStrings } from "./part-type-strings";
export const quotePageDiscountTable = [
// Repair
{
name: "Repair Glass Only",
experimentCode: "Show_GlassOnly_Repair_Discount",
partNumber: "GL RPR CSH PKG",
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
description: "GLASS RPR GEOTARGET DISC",
packageLevel: packageNames.TIER_ONE,
},
{
name: "Repair Standard",
experimentCode: "Show_Standard_Repair_Discount",
partNumber: "STD RPR CSH PKG",
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
description: "STD RPR GEOTARGET DISC",
packageLevel: packageNames.TIER_TWO,
},
{
name: "Repair Premium",
experimentCode: "Show_Premium_Repair_Discount",
partNumber: "PRM RPR CSH PKG",
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
description: "PREM RPR GEOTARGET DISC",
packageLevel: packageNames.TIER_THREE,
},
// Replace - No recal
{
name: "Replace Glass Only",
experimentCode: "Show_GlassOnly_Replace_Discount",
partNumber: "GL RPL CSH PKG",
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
description: "GLASS RPL GEOTARGET DISC",
packageLevel: packageNames.TIER_ONE,
},
{
name: "Replace Standard",
experimentCode: "Show_Standard_Replace_Discount",
partNumber: "STD RPL CSH PKG",
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
description: "STD RPL GEOTARGET DISC",
packageLevel: packageNames.TIER_TWO,
},
{
name: "Replace Premium",
experimentCode: "Show_Premium_Replace_Discount",
partNumber: "PRM RPL CSH PKG",
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
description: "PREM RPL GEOTARGET DISC",
packageLevel: packageNames.TIER_THREE,
},
// Replace - with recal
{
name: "Recal Glass Only",
experimentCode: "Show_GlassOnly_Recal_Discount",
partNumber: "GL RCL CSH PKG",
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
description: "GLASS RCL GEOTARGET DISC",
packageLevel: packageNames.TIER_ONE,
},
{
name: "Recal Standard",
experimentCode: "Show_Standard_Recal_Discount",
partNumber: "STD RCL CSH PKG",
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
description: "STD RCL GEOTARGET DISC",
packageLevel: packageNames.TIER_TWO,
},
{
name: "Recal Premium",
experimentCode: "Show_Premium_Recal_Discount",
partNumber: "PRM RCL CSH PKG",
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
description: "PREM RCL GEOTARGET DISC",
packageLevel: packageNames.TIER_THREE,
},
];

View file

@ -145,7 +145,9 @@ export default {
return "$" + decimalPrice.toFixed(2);
},
hasPackageDiscount() {
return this.additionalButtonData.hasDiscount && this.additionalButtonData.Text;
return (
this.additionalButtonData.servicePackageDiscount && this.additionalButtonData.Text
);
},
},
};

View file

@ -4,11 +4,11 @@
class="package-label pricing-by-day-pkg-lbl"
:class="[
this.buttonLabelSubCopy ? 'has-subheader' : '',
!this.additionalButtonData.hasDiscount ? 'adjust-top' : '',
!this.additionalButtonData.servicePackageDiscount ? 'adjust-top' : '',
]"
for="testradio">
<div class="package-specs">
<div v-if="this.additionalButtonData.hasDiscount" class="row">
<div v-if="this.additionalButtonData.servicePackageDiscount" class="row">
<div class="col md-6">
<p class="m-0">
<span v-html="this.buttonLabel"></span>
@ -84,7 +84,10 @@
</div>
<div
v-if="this.additionalButtonData.hasDiscount && this.additionalButtonData.Text"
v-if="
this.additionalButtonData.servicePackageDiscount &&
this.additionalButtonData.Text
"
class="special-save-box">
<span v-html="this.additionalButtonData.Text"></span>
</div>

View file

@ -190,7 +190,6 @@ import { cartItemCategories } from "@/constants/cart-item-categories";
import { cartItemTypes } from "@/constants/cart-item-types";
import { coverageStatus, cartItemTypesCoveredByInsurance } from "@/constants/insurance";
import { experimentSettings } from "@/constants/experiments";
import { quotePageDiscountTable } from "@/constants/quote-page-discounts";
export default {
name: "cart",
@ -257,11 +256,11 @@ export default {
return subTotal;
},
getQuotePageDiscount() {
const quotePageDiscountLineItems = this.quotePageDiscountCartItem;
getServicePackageDiscount() {
const servicePackageDiscountLineItems = this.servicePackageDiscountCartItem;
let subTotal = 0;
subTotal += quotePageDiscountLineItems?.subTotal ?? 0;
subTotal += servicePackageDiscountLineItems?.subTotal ?? 0;
return subTotal;
},
getVapsCartItemsForSelectedPackage(packageName) {
@ -304,8 +303,7 @@ export default {
getLineItemAmount(amount, useVerifyingText, category) {
if (useVerifyingText) return this.verifyingCoverageText;
return category == cartItemCategories.PROMOS ||
category == cartItemCategories.QUOTE_PAGE_DISCOUNT
return category == "promos" || category == "servicePackageDiscount"
? "(" + this.currencyFormatter.format(amount * -1) + ")"
: this.currencyFormatter.format(amount);
},
@ -318,21 +316,16 @@ export default {
if (category == cartItemCategories.VAPS || category == cartItemCategories.PROMOS) {
this.saveVaps(this.lineItems);
// Check if service package discount should be removed after vaps change
if (this.quotePageDiscountCartItem) {
const existingLineItem = this.quotePageDiscountCartItem.lineItems.at(0);
const discountInfo = quotePageDiscountTable.find(
(info) => info.partNumber === existingLineItem?.partNumber
if (
this.servicePackageDiscountCartItem &&
this.discountPackageNames != this.packageLevel
) {
this.lineItems.supportingItems = this.lineItems.supportingItems.filter(
(lineItemsToKeep) =>
lineItemsToKeep.cartItemType !=
this.servicePackageDiscountCartItem.cartItemType
);
const packageLevelForDiscount = discountInfo?.packageLevel;
if (this.packageLevel !== packageLevelForDiscount) {
this.lineItems.supportingItems = this.lineItems.supportingItems.filter(
(lineItemsToKeep) =>
lineItemsToKeep.cartItemType !=
this.quotePageDiscountCartItem.cartItemType
);
shouldSaveSupportingItems = true;
}
shouldSaveSupportingItems = true;
}
}
if (shouldSaveSupportingItems) {
@ -490,8 +483,8 @@ export default {
cartItems.push(this.mobileFeeCartItem);
}
if (this.quotePageDiscountCartItem) {
cartItems.push(this.quotePageDiscountCartItem);
if (this.servicePackageDiscountCartItem) {
cartItems.push(this.servicePackageDiscountCartItem);
}
if (this.premiumAppointmentDiscountCartItem) {
@ -507,6 +500,12 @@ export default {
return cartItems;
},
},
discountPackageNames() {
const discountServicePackage = experimentMixin.methods.getSettingValue(
experimentSettings.PROMO_ON_PACKAGE
);
return getDiscountedPackageName(discountServicePackage);
},
servicePackageTitleWidget() {
const servicePackageNames = this.getCmsContent(
this.servicePackageOptionsCmsName,
@ -551,8 +550,8 @@ export default {
}
packagePrice += this.getVapsPrice(this.packageLevel);
if (this.quotePageDiscountCartItem) {
packagePrice -= this.getQuotePageDiscount();
if (this.servicePackageDiscountCartItem) {
packagePrice -= this.getServicePackageDiscount();
}
return packagePrice;
@ -929,25 +928,25 @@ export default {
}
return cartItem;
},
quotePageDiscountCartItemName() {
servicePackageDiscountCartItemName() {
return this.getCmsContent("ServicePackageDiscountTextWidget", "Text");
},
quotePageDiscountCartItem() {
servicePackageDiscountCartItem() {
let cartItem = null;
const quotePageDiscountLineItem = this.supportingItems.find(
(lineItem) => lineItem.partType == partTypeStrings.QUOTE_PAGE_DISCOUNT
const servicePackageDiscountLineItem = this.supportingItems.find(
(lineItem) => lineItem.partType == partTypeStrings.SERVICE_PACKAGE_DISCOUNT
);
if (quotePageDiscountLineItem) {
if (servicePackageDiscountLineItem) {
cartItem = {
name:
this.quotePageDiscountCartItemName +
this.servicePackageDiscountCartItemName +
Math.abs(
baseMixin.methods.getTotalLineItemPrice(quotePageDiscountLineItem)
baseMixin.methods.getTotalLineItemPrice(servicePackageDiscountLineItem)
),
category: cartItemCategories.QUOTE_PAGE_DISCOUNT,
cartItemType: cartItemTypes.QUOTE_PAGE_DISCOUNT,
category: cartItemCategories.SERVICE_PACKAGE_DISCOUNT,
cartItemType: cartItemTypes.SERVICE_PACKAGE_DISCOUNT,
isDisplayed: true,
isRemovable: false,
subTotal: 0,
@ -956,15 +955,15 @@ export default {
isCoveredByInsurance: false,
};
quotePageDiscountLineItem.cartItemType = cartItem.cartItemType;
cartItem.lineItems.push(quotePageDiscountLineItem);
servicePackageDiscountLineItem.cartItemType = cartItem.cartItemType;
cartItem.lineItems.push(servicePackageDiscountLineItem);
cartItem.subTotal +=
(quotePageDiscountLineItem.kitPrice ?? 0) +
(quotePageDiscountLineItem.laborAmount ?? 0) +
(quotePageDiscountLineItem.sellingPrice ?? 0);
(servicePackageDiscountLineItem.kitPrice ?? 0) +
(servicePackageDiscountLineItem.laborAmount ?? 0) +
(servicePackageDiscountLineItem.sellingPrice ?? 0);
cartItem.salesTax += quotePageDiscountLineItem.salesTax ?? 0;
cartItem.salesTax += servicePackageDiscountLineItem.salesTax ?? 0;
}
return cartItem;
@ -973,7 +972,7 @@ export default {
let cartItem = null;
const otherSupportingItems = this.supportingItems.filter((item) => {
return item.partType != partTypeStrings.QUOTE_PAGE_DISCOUNT;
return item.partType != partTypeStrings.SERVICE_PACKAGE_DISCOUNT;
});
// Don't include fees they are part of the package total
let otherSupportingItemsLineItems =

View file

@ -82,7 +82,7 @@ jest.mock("@/mixins/base-mixin", () => ({
filterOutFees(items) {
return null;
},
filterOutQuotePageDiscountPart(items) {
filterOutServicePackageDiscountPart(items) {
return null;
},
isFormValid(form) {

View file

@ -31,11 +31,10 @@
:isRecalibrationOnOrder="isRecalibrationOnOrder"
:shouldHideRecalibration="shouldHideRecalibration"
@vapsItemsSelected="vapsItemsSelectedAction"
@quotePageDiscountSelected="quotePageDiscountSelectedAction"
@servicePackageDiscountSelected="servicePackageDiscountSelectedAction"
@currentNumberOfPackages="currentNumberOfPackagesAction"
:servicePackage="servicePackage"
:activePromos="lineItems.promos"
:availableQuotePageDiscounts="quoteDiscountPartsInfo"
v-on="{ 'buttonEvent.openModal': openModalAction }"
validationRules="option-required"
isRequired />
@ -177,7 +176,6 @@ import { consumeQueryFromStash } from "@/router/methods/helpers/querystring-stas
import { storeMutations } from "@/constants/store-mutations";
import { debugLog } from "@/helpers/debug-log-helper";
import { savePageData } from "@/router/methods/helpers/save-page-data";
import { quotePageDiscountTable } from "../../constants/quote-page-discounts";
defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
@ -188,14 +186,6 @@ const ACCEPTED_QUOTE_TYPES = {
INSURANCE: "insurance",
};
function getAvailableQuotePageDiscounts() {
const activeDiscounts = quotePageDiscountTable?.filter((discountEntry) =>
experimentMixin?.methods?.hasSettingEqualTo(discountEntry?.experimentCode, "true")
);
return activeDiscounts ?? [];
}
export default {
name: "quote",
async beforeRouteEnter(to, from, next) {
@ -312,22 +302,29 @@ export default {
const lineItems = deepClone(store.getters.order.lineItems);
lineItems.vaps = lineItems.vaps ?? [];
const nullSafeGlassParts = lineItems.glassParts ?? [];
const quotePageDiscountPartsInfo = getAvailableQuotePageDiscounts();
const quotePageDiscountParts = quotePageDiscountPartsInfo.map((partInfo) => ({
partNumber: partInfo.partNumber,
partType: partInfo.partType,
description: partInfo.description,
isInsurable: null,
}));
const servicePackageDiscountSettingValue = experimentMixin.methods.getSettingValue(
experimentSettings.SERVICE_PACKAGE_DISCOUNT
);
const isServicePackageDiscount = servicePackageDiscountSettingValue === "True";
//Service package cash discount api call when experiment is active
var servicePackageDiscountPart = [];
if (isServicePackageDiscount) {
const servicePackageDiscountPartResponse =
await baseMixin.methods.dispatchStoreActionWithLogging(
storeActions.GET_SERVICE_PACKAGE_DISCOUNT_PART,
null,
"quote"
);
if (servicePackageDiscountPartResponse.data) {
servicePackageDiscountPart.push(servicePackageDiscountPartResponse.data);
}
}
const availableLineItems = [
resultMap.rainRepel,
...resultMap.supportingItems,
...resultMap.wipers,
...nullSafeGlassParts,
...quotePageDiscountParts,
...servicePackageDiscountPart,
];
// When calling pricing from the quote page, always use the cash parent account but save the existing one in case it's unverified insurance navigating backwards
@ -354,7 +351,7 @@ export default {
false
);
// This will remove any discount item from lineItems.supportingItems
// This will remove any servicePackageDiscount item from lineItems.supportingItems
baseMixin.methods.dispatchStoreAction(
storeActions.SAVE_SUPPORTING_ITEMS,
resultMap.supportingItems,
@ -456,9 +453,10 @@ export default {
)
: baseMixin.methods.filterOutFees(availableLineItems);
const lineItemsNoDiscount = baseMixin.methods.filterOutQuotePageDiscountPart(
lineItemsForCalculatingPrice
);
const lineItemsNoDiscount =
baseMixin.methods.filterOutServicePackageDiscountPart(
lineItemsForCalculatingPrice
);
if (isInsuranceFromQueryString != null) {
if (isInsuranceFromQueryString.toLowerCase() === "true") {
@ -582,8 +580,17 @@ export default {
isRecalibrationOnOrder() {
return store.getters.isRecalibrationOnOrder;
},
isQuotePageDiscountOnOrder() {
return this.quotePageDiscountPartsInfo?.length > 0;
isServicePackageDiscountOnOrder() {
return containsLineItemWithPartType(
partTypeStrings.SERVICE_PACKAGE_DISCOUNT,
this.availableLineItems
);
},
servicePackageDiscountParts() {
return findLineItemsWithPartType(
partTypeStrings.SERVICE_PACKAGE_DISCOUNT,
this.availableLineItems
);
},
shouldHideRecalibration() {
return (
@ -612,23 +619,6 @@ export default {
thresholdAmount && (thresholdAmount = parseInt(thresholdAmount));
return thresholdAmount;
},
quoteDiscountPartsInfo() {
const defs = getAvailableQuotePageDiscounts();
const withPrices = defs
.map((def) => {
const match = this.availableLineItems?.find?.(
(pricedItem) => pricedItem.partNumber === def.partNumber
);
return {
packageLevel: def.packageLevel,
item: match,
};
})
.filter((result) => result.item);
return withPrices;
},
},
methods: {
getColCount() {
@ -672,7 +662,7 @@ export default {
vapsItemsSelectedAction(vapsItemsSelected) {
this.lineItems.vaps = vapsItemsSelected;
},
quotePageDiscountSelectedAction(supportingItemsSelected) {
servicePackageDiscountSelectedAction(supportingItemsSelected) {
this.lineItems.supportingItems = supportingItemsSelected;
},
backButtonAction() {
@ -734,10 +724,10 @@ export default {
false
);
}
if (this.isInsuranceSelected && this.isQuotePageDiscountOnOrder) {
if (this.isInsuranceSelected && this.isServicePackageDiscountOnOrder) {
let supportingItems = this.lineItems.supportingItems;
supportingItems = supportingItems.filter((item) => {
return item.partType != partTypeStrings.QUOTE_PAGE_DISCOUNT;
return item.partType != this.servicePackageDiscountParts[0].partType;
});
this.dispatchStoreAction(
this.storeActions.SAVE_SUPPORTING_ITEMS,
@ -823,23 +813,19 @@ export default {
lineItemsToPrice =
baseMixin.methods.filterOutRecalibration(lineItemsToPrice);
}
if (this.isQuotePageDiscountOnOrder) {
if (this.isServicePackageDiscountOnOrder) {
lineItemsToPrice = lineItemsToPrice?.filter((item) => {
return item.partType != partTypeStrings.QUOTE_PAGE_DISCOUNT;
return (
item.partType != this.servicePackageDiscountParts[0].partType
);
});
}
let price = 0;
if (
tier.additionalButtonData?.hasDiscount &&
this.isQuotePageDiscountOnOrder
tier.additionalButtonData?.servicePackageDiscount &&
this.isServicePackageDiscountOnOrder
) {
const parts = this.quoteDiscountPartsInfo;
const matchPart = parts.find(
(discountInfo) => discountInfo.packageLevel === tier
);
if (matchPart) {
lineItemsToPrice.push(matchPart);
}
lineItemsToPrice.push(...this.servicePackageDiscountParts);
}
price += baseMixin.methods.getTierOnePackagePrice(
baseMixin.methods.filterOutFees(lineItemsToPrice)

View file

@ -14,7 +14,6 @@ import { experimentSettings } from "@/constants/experiments";
import baseMixin from "@/mixins/base-mixin.js";
import { partTypeStrings } from "@/constants/part-type-strings";
import { nextTick } from "vue";
import { packageNames } from "../../../constants/package-names";
jest.mock("@/store", () => ({
commit: jest.fn(),
@ -74,9 +73,9 @@ describe("service-package-question.vue", () => {
price: 35.5,
},
{
partNumber: "PRM RCL CSH PKG",
partNumber: "DISC CASHSAVE70",
description: null,
partType: "QUOTE PAGE DISCOUNT",
partType: "SERVICE PACKAGE DISCOUNT",
price: -70,
},
],
@ -106,27 +105,13 @@ describe("service-package-question.vue", () => {
description: null,
kitPrice: 0,
laborAmount: 0,
partNumber: "PRM RCL CSH PKG",
partType: "QUOTE PAGE DISCOUNT",
partNumber: "DISC CASHSAVE70",
partType: "SERVICE PACKAGE DISCOUNT",
salesTax: null,
sellingPrice: -70,
},
],
},
availableQuotePageDiscounts: [
{
packageLevel: packageNames.TIER_THREE,
item: {
description: null,
kitPrice: 0,
laborAmount: 0,
partNumber: "PRM RCL CSH PKG",
partType: "QUOTE PAGE DISCOUNT",
salesTax: null,
sellingPrice: -70,
},
},
],
activePromos: [],
};
const packageNameKey = "05_01_CSR_Quote_Standard_Repair";
@ -151,17 +136,41 @@ describe("service-package-question.vue", () => {
});
it("should return price when there is discount", () => {
const wrapper = setupMocks({});
const partType = partTypeStrings.SERVICE_PACKAGE_DISCOUNT;
const price = wrapper.vm.getDiscountPrice(packageNames.TIER_THREE);
wrapper.vm.isServicePackageDiscountOnOrder = containsLineItemWithPartType(
partType,
mockProps.lineItems.supportingItems
);
const servicePackageDiscountLineItem = findLineItemsWithPartType(
partType,
mockProps.lineItems.supportingItems
);
wrapper.vm.getServicePackageDiscountPrice();
const price = baseMixin.methods.getTotalLineItemPrice(servicePackageDiscountLineItem[0]);
expect(Math.abs(price)).toEqual(70);
});
it("isDiscountOnOrder returns true if it contains quote package discount lineItems", () => {
it("isServicePackageDiscountOnOrder returns true if it contains service package discount lineItems", () => {
// Arrange
const wrapper = setupMocks({});
// Assert
expect(wrapper.vm.isDiscountOnOrder).toBe(true);
expect(wrapper.vm.isServicePackageDiscountOnOrder).toBe(true);
});
it("servicePackageDiscountParts should returns service package discount lineItems", () => {
// Arrange
const wrapper = setupMocks({});
// Assert
expect(wrapper.vm.servicePackageDiscountParts).toEqual([
{
partNumber: "DISC CASHSAVE70",
description: null,
partType: "SERVICE PACKAGE DISCOUNT",
price: -70,
},
]);
});
it("should have the correct insurance pricing text when insurance is selected", () => {
// Arrange

View file

@ -60,7 +60,6 @@ export default {
servicePackage: null,
isRecalibrationOnOrder: Boolean,
shouldHideRecalibration: Boolean,
availableQuotePageDiscounts: null,
},
data() {
return {
@ -86,18 +85,27 @@ export default {
selectedPackageName(newValue) {
const VapsProductsInSelectedPackage = this.getVapsLineItemsForSelectedPackage(newValue);
this.$emit("vapsItemsSelected", VapsProductsInSelectedPackage);
const discountPartInSelectedPackage = this.getDiscountPartForSelectedPackage(newValue);
const servicePackageDiscountPartInSelectedPackage =
this.getServicePackageDiscountPartForSelectedPackage(newValue);
let supportingItems = this.supportingLineItems;
supportingItems = supportingItems.filter(
(item) => item.partType !== partTypeStrings.QUOTE_PAGE_DISCOUNT
);
if (discountPartInSelectedPackage) {
supportingItems.push(discountPartInSelectedPackage);
if (
containsLineItemWithPartType(
partTypeStrings.SERVICE_PACKAGE_DISCOUNT,
supportingItems
)
) {
supportingItems = supportingItems.filter(
(item) => item.partType !== partTypeStrings.SERVICE_PACKAGE_DISCOUNT
);
}
if (
servicePackageDiscountPartInSelectedPackage?.length > 0 &&
supportingItems != null
) {
supportingItems.push(servicePackageDiscountPartInSelectedPackage[0]);
}
this.$emit("quotePageDiscountSelected", supportingItems);
this.$emit("servicePackageDiscountSelected", supportingItems);
},
servicePackage(newValue) {
if (newValue !== null) {
@ -110,7 +118,7 @@ export default {
return this.availableLineItems ?? [];
},
supportingLineItems() {
return this.$store.getters.lineItems?.supportingItems ?? [];
return this.$store.getters.lineItems?.supportingItems;
},
servicePackageAnswers() {
const cmsWidgetName = this.isInsuranceSelected
@ -141,15 +149,18 @@ export default {
? this.getDiscountedPackagePriceString(answer.Name, false)
: this.getDiscountedPackagePriceString(
answer.Name,
this.hasDiscountForPackage(answer.Name)
this.isServicePackageDiscountOnOrder &&
this.discountPackageNames == answer.Name
),
buttonFooterCopy: this.getFooterTextFromCms(answer.SubWidgetName),
additionalButtonData: {
strikeThroughPrice: this.getPackagePriceString(answer.Name),
hasDiscount: this.hasDiscountForPackage(answer.Name),
servicePackageDiscount:
this.isServicePackageDiscountOnOrder &&
this.discountPackageNames == answer.Name,
Text: this.isInsuranceSelected
? false
: "Special: Save $" + this.getDiscountPrice(answer.Name),
: "Special: Save $" + this.getServicePackageDiscountPrice(),
isInsuranceSelected: this.isInsuranceSelected,
},
}));
@ -157,8 +168,17 @@ export default {
this.$emit("currentNumberOfPackages", modifiedAnswers.length);
return modifiedAnswers;
},
isDiscountOnOrder() {
return this.availableQuotePageDiscounts?.length > 0;
isServicePackageDiscountOnOrder() {
return containsLineItemWithPartType(
partTypeStrings.SERVICE_PACKAGE_DISCOUNT,
this.nullSafeAvailableLineItems
);
},
discountPackageNames() {
const discountServicePackage = experimentMixin.methods.getSettingValue(
experimentSettings.PROMO_ON_PACKAGE
);
return getDiscountedPackageName(discountServicePackage);
},
frontWipersApplicableForTierTwo() {
return shouldFrontWipersBeAvailable(
@ -206,6 +226,12 @@ export default {
isRepair() {
return this.$store.getters.order.damage.isRepair;
},
servicePackageDiscountParts() {
return findLineItemsWithPartType(
partTypeStrings.SERVICE_PACKAGE_DISCOUNT,
this.nullSafeAvailableLineItems
);
},
showRecalInServicePackages() {
return this.isRecalibrationOnOrder && !this.shouldHideRecalibration;
},
@ -254,16 +280,16 @@ export default {
const formattedPriceFloat = parseFloat(
this.getPackagePrice(packageName, {
discountedPrice: false,
quotePageDiscount: false,
servicePackageDiscount: false,
})
).toFixed(2);
return "$" + formattedPriceFloat;
},
getDiscountedPackagePriceString(packageName, quotePageDiscount) {
getDiscountedPackagePriceString(packageName, servicePackageDiscount) {
const formattedPriceFloat = parseFloat(
this.getPackagePrice(packageName, {
discountedPrice: true,
quotePageDiscount,
servicePackageDiscount,
})
).toFixed(2);
@ -272,7 +298,7 @@ export default {
}
return (this.isInsuranceSelected ? "As little as $" : "$") + formattedPriceFloat;
},
getPackagePrice(packageName, { discountedPrice = false, quotePageDiscount = false }) {
getPackagePrice(packageName, { discountedPrice = false, servicePackageDiscount = false }) {
let lineItemsToPrice = [...this.nullSafeAvailableLineItems];
if (this.isRecalibrationOnOrder && this.shouldHideRecalibration) {
@ -280,20 +306,17 @@ export default {
}
//remove service package discount part
if (this.isDiscountOnOrder) {
if (this.isServicePackageDiscountOnOrder) {
lineItemsToPrice = lineItemsToPrice.filter((item) => {
return item.partType != partTypeStrings.QUOTE_PAGE_DISCOUNT;
return item.partType != this.servicePackageDiscountParts[0].partType;
});
}
if (discountedPrice) {
lineItemsToPrice.push(...removeVapsPromosFromPromoArray(this.activePromos));
}
if (quotePageDiscount) {
const part = this.getDiscountPartForSelectedPackage(packageName);
if (part) {
lineItemsToPrice.push(part);
}
if (servicePackageDiscount) {
lineItemsToPrice.push(...this.servicePackageDiscountParts);
}
let priceFloat = this.isInsuranceSelected
? 0
@ -305,16 +328,14 @@ export default {
return priceFloat;
},
getDiscountPrice(packageName) {
const part = this.getDiscountPartForSelectedPackage(packageName);
if (part) {
const price = baseMixin.methods.getTotalLineItemPrice(part);
getServicePackageDiscountPrice() {
if (this.isServicePackageDiscountOnOrder) {
let price = 0;
price += baseMixin.methods.getTotalLineItemPrice(
this.servicePackageDiscountParts[0]
);
return Math.abs(price);
}
return null;
},
getVapsPrice(packageName, applyPromoDiscounts = false) {
const vapsItems = this.getVapsLineItemsForSelectedPackage(packageName);
@ -377,18 +398,13 @@ export default {
return vapsLineItemsForSelectedPackage;
},
getDiscountPartForSelectedPackage(packageName) {
if (this.availableQuotePageDiscounts?.length > 0) {
const match = this.availableQuotePageDiscounts.find(
(discountInfo) => discountInfo.packageLevel === packageName
);
return match?.item;
}
return null;
},
hasDiscountForPackage(packageName) {
return !!this.getDiscountPartForSelectedPackage(packageName);
getServicePackageDiscountPartForSelectedPackage(packageName) {
const selectedPackage = this.servicePackageAnswers.filter(
(item) => item.value === packageName
);
if (selectedPackage?.[0]?.additionalButtonData?.servicePackageDiscount) {
return this.servicePackageDiscountParts;
} else return [];
},
combineLineItemsWithoutDuplicates(lineItemsOne, lineItemsTwo) {
const combinedLineItemArray = [...lineItemsTwo];

View file

@ -5,7 +5,7 @@
:class="[this.buttonLabelSubCopy ? 'has-subheader' : '']"
for="testradio">
<div class="package-specs">
<div v-if="this.additionalButtonData.hasDiscount" class="row">
<div v-if="this.additionalButtonData.servicePackageDiscount" class="row">
<div class="col md-6">
<p class="m-0">
<span v-html="this.buttonLabel"></span>
@ -77,7 +77,10 @@
</div>
<div
v-if="this.additionalButtonData.hasDiscount && this.additionalButtonData.Text"
v-if="
this.additionalButtonData.servicePackageDiscount &&
this.additionalButtonData.Text
"
class="special-save-box">
<span v-html="this.additionalButtonData.Text"></span>
</div>

View file

@ -129,9 +129,9 @@ export default {
});
return lineItemsArray;
},
filterOutQuotePageDiscountPart(lineItems) {
filterOutServicePackageDiscountPart(lineItems) {
const filteredLineItems = lineItems?.filter((item) => {
return !item?.partType?.includes(partTypeStrings.QUOTE_PAGE_DISCOUNT);
return !item?.partType?.includes(partTypeStrings.SERVICE_PACKAGE_DISCOUNT);
});
return filteredLineItems;
},