Implementation of validate and revalidate endpoints in the store Validate promo on quote via query string promo Revalidate promos on quote page load Remove promo query string on quote and payment-method forward navigation Add in Id logic for all line items Send relevant pricing data to service package question to be used later for UX changes
270 lines
9.9 KiB
Vue
270 lines
9.9 KiB
Vue
<template>
|
|
<buttonQuestion
|
|
ref="buttonQuestion"
|
|
:answers="servicePackageAnswers"
|
|
:groupName="groupName"
|
|
buttonTypeString="servicePackageRadio"
|
|
:buttonTypeObject="servicePackageRadio"
|
|
v-model="selectedPackageName"
|
|
:validationRules="validationRules"
|
|
:isRequired="isRequired"
|
|
:logDisplayedValuesEvent="true" />
|
|
</template>
|
|
|
|
<script>
|
|
import buttonQuestion from "@/digital-components/button-question/button-question";
|
|
import baseMixin from "@/mixins/base-mixin.js";
|
|
import { processIfStatements } from "@/helpers/cms-content-helper";
|
|
import { damageLocationsSelected as glassLocations } from "@/constants/damage-locations-selected";
|
|
import servicePackageRadio from "./service-package-radio/service-package-radio";
|
|
import { partTypeStrings } from "@/constants/part-type-strings";
|
|
import { packageNames } from "@/constants/package-names";
|
|
import {
|
|
shouldFrontWipersBeAvailable,
|
|
shouldRearWipersBeAvailable,
|
|
shouldRainDefenseBeAvailable,
|
|
getAvailablePackages,
|
|
getHighestRequiredTier,
|
|
getPackageContents,
|
|
containsLineItemWithPartType,
|
|
findLineItemsWithPartType,
|
|
} from "@/helpers/service-package-helper";
|
|
import {
|
|
getPromosThatMatchLineItemsOnOrder,
|
|
removeVapsPromosFromPromoArray,
|
|
} from "@/helpers/promotions-helper";
|
|
|
|
export default {
|
|
name: "servicePackageQuestion",
|
|
props: {
|
|
groupName: String,
|
|
cashCmsWidgetName: String,
|
|
insuranceCmsWidgetName: String,
|
|
validationRules: String,
|
|
isRequired: Boolean,
|
|
isInsuranceSelected: Boolean,
|
|
availableLineItems: null,
|
|
activePromos: null,
|
|
},
|
|
data() {
|
|
return {
|
|
servicePackageRadio: servicePackageRadio,
|
|
selectedPackageName: null,
|
|
};
|
|
},
|
|
watch: {
|
|
availableLineItems() {
|
|
if (this.$store.getters.payment.isInsurance != null) {
|
|
this.selectDefaultPackage();
|
|
}
|
|
},
|
|
selectedPackageName(newValue) {
|
|
const VapsProductsInSelectedPackage = this.getVapsLineItemsForSelectedPackage(newValue);
|
|
this.$emit("vapsItemsSelected", VapsProductsInSelectedPackage);
|
|
},
|
|
},
|
|
computed: {
|
|
nullSafeAvailableLineItems() {
|
|
return this.availableLineItems ?? [];
|
|
},
|
|
servicePackageAnswers() {
|
|
const cmsWidgetName = this.isInsuranceSelected
|
|
? this.insuranceCmsWidgetName
|
|
: this.cashCmsWidgetName;
|
|
let cmsAnswersContent = this.getCmsContent(cmsWidgetName, "Answers");
|
|
if (!cmsAnswersContent) {
|
|
return null;
|
|
}
|
|
|
|
const availablePackages = getAvailablePackages(
|
|
this.glassToReplace,
|
|
this.nullSafeAvailableLineItems,
|
|
this.isRepair
|
|
);
|
|
|
|
cmsAnswersContent = cmsAnswersContent.filter((answer) =>
|
|
availablePackages.some((tier) => answer.Name === tier.packageName)
|
|
);
|
|
|
|
const modifiedAnswers = cmsAnswersContent.map((answer) => ({
|
|
value: answer.Name,
|
|
buttonLabel: this.getHeaderTextFromCms(answer.SubWidgetName),
|
|
buttonLabelSubCopy: this.getSubheaderTextFromCms(answer.SubWidgetName),
|
|
buttonBodyCopy: this.getBodyTextFromCms(answer.SubWidgetName),
|
|
buttonAuxillaryCopy: this.getDiscountedPackagePriceString(answer.Name),
|
|
buttonFooterCopy: this.getFooterTextFromCms(answer.SubWidgetName),
|
|
additionalButtonData: {
|
|
strikeThroughPrice: this.getPackagePriceString(answer.Name),
|
|
},
|
|
}));
|
|
return modifiedAnswers;
|
|
},
|
|
isRecalibrationOnOrder() {
|
|
return containsLineItemWithPartType(
|
|
partTypeStrings.RECALIBRATION,
|
|
this.nullSafeAvailableLineItems
|
|
);
|
|
},
|
|
frontWipersApplicableForTierTwo() {
|
|
return shouldFrontWipersBeAvailable(
|
|
this.glassToReplace,
|
|
this.nullSafeAvailableLineItems,
|
|
this.isRepair,
|
|
packageNames.TIER_TWO
|
|
);
|
|
},
|
|
rearWiperApplicableForTierTwo() {
|
|
return shouldRearWipersBeAvailable(
|
|
this.glassToReplace,
|
|
this.nullSafeAvailableLineItems,
|
|
this.isRepair,
|
|
packageNames.TIER_TWO
|
|
);
|
|
},
|
|
frontWipersApplicableForTierThree() {
|
|
return shouldFrontWipersBeAvailable(
|
|
this.glassToReplace,
|
|
this.nullSafeAvailableLineItems,
|
|
this.isRepair,
|
|
packageNames.TIER_THREE
|
|
);
|
|
},
|
|
rearWiperApplicableForTierThree() {
|
|
return shouldRearWipersBeAvailable(
|
|
this.glassToReplace,
|
|
this.nullSafeAvailableLineItems,
|
|
this.isRepair,
|
|
packageNames.TIER_THREE
|
|
);
|
|
},
|
|
rainDefenseApplicableForTierThree() {
|
|
return shouldRainDefenseBeAvailable(
|
|
this.glassToReplace,
|
|
this.nullSafeAvailableLineItems,
|
|
this.isRepair,
|
|
packageNames.TIER_THREE
|
|
);
|
|
},
|
|
glassToReplace() {
|
|
return this.$store.getters.order.damage.glassToReplace;
|
|
},
|
|
isRepair() {
|
|
return this.$store.getters.order.damage.isRepair;
|
|
},
|
|
},
|
|
methods: {
|
|
processIfStatements,
|
|
getHeaderTextFromCms(cmsWidgetName) {
|
|
return this.getCmsContent(cmsWidgetName, "HeaderText");
|
|
},
|
|
getSubheaderTextFromCms(cmsWidgetName) {
|
|
return this.getCmsContent(cmsWidgetName, "SubheaderText");
|
|
},
|
|
getBodyTextFromCms(cmsWidgetName) {
|
|
const bodyText = this.getCmsContent(cmsWidgetName, "BodyText");
|
|
return this.processIfStatements(bodyText, "custom", this.getCustomValueFromString);
|
|
},
|
|
getFooterTextFromCms(cmsWidgetName) {
|
|
const footerText = this.getCmsContent(cmsWidgetName, "FooterText");
|
|
return this.processIfStatements(footerText, "custom", this.getCustomValueFromString);
|
|
},
|
|
getPackagePriceString(packageName) {
|
|
const formattedPriceFloat = parseFloat(
|
|
this.getPackagePrice(packageName, { discountedPrice: false })
|
|
).toFixed(2);
|
|
return "$" + formattedPriceFloat;
|
|
},
|
|
getDiscountedPackagePriceString(packageName) {
|
|
const formattedPriceFloat = parseFloat(
|
|
this.getPackagePrice(packageName, { discountedPrice: true })
|
|
).toFixed(2);
|
|
return (this.isInsuranceSelected ? "As little as $" : "$") + formattedPriceFloat;
|
|
},
|
|
getPackagePrice(packageName, { discountedPrice = false }) {
|
|
const lineItemsToPrice = [...this.nullSafeAvailableLineItems];
|
|
if (discountedPrice) {
|
|
lineItemsToPrice.push(...removeVapsPromosFromPromoArray(this.activePromos));
|
|
}
|
|
let priceFloat = this.isInsuranceSelected
|
|
? 0
|
|
: baseMixin.methods.getTierOnePackagePrice(
|
|
baseMixin.methods.filterOutFees(lineItemsToPrice)
|
|
);
|
|
|
|
priceFloat += this.getVapsPrice(packageName, discountedPrice);
|
|
|
|
return priceFloat;
|
|
},
|
|
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.activePromos,
|
|
vapsItems
|
|
);
|
|
relevantPromos.forEach((promo) => {
|
|
price += baseMixin.methods.getTotalLineItemPrice(promo);
|
|
});
|
|
}
|
|
|
|
return price;
|
|
},
|
|
selectDefaultPackage() {
|
|
const vapsFromStore = this.$store.getters.lineItems.vaps ?? [];
|
|
|
|
this.selectedPackageName = getHighestRequiredTier(
|
|
this.glassToReplace,
|
|
this.nullSafeAvailableLineItems,
|
|
this.isRepair,
|
|
vapsFromStore
|
|
);
|
|
},
|
|
getVapsLineItemsForSelectedPackage(packageName) {
|
|
const packageContentTypes = getPackageContents(
|
|
this.glassToReplace,
|
|
this.nullSafeAvailableLineItems,
|
|
this.isRepair,
|
|
packageName
|
|
);
|
|
|
|
let vapsLineItemsForSelectedPackage = [];
|
|
|
|
packageContentTypes.forEach((vapType) => {
|
|
vapsLineItemsForSelectedPackage.push(
|
|
...findLineItemsWithPartType(vapType, this.nullSafeAvailableLineItems)
|
|
);
|
|
});
|
|
|
|
return vapsLineItemsForSelectedPackage;
|
|
},
|
|
getCustomValueFromString(str) {
|
|
switch (str) {
|
|
case "isRecalibrationOnOrder":
|
|
return this.isRecalibrationOnOrder;
|
|
case "frontWipersApplicableForTierTwo":
|
|
return this.frontWipersApplicableForTierTwo;
|
|
case "rearWiperApplicableForTierTwo":
|
|
return this.rearWiperApplicableForTierTwo;
|
|
case "frontWipersApplicableForTierThree":
|
|
return this.frontWipersApplicableForTierThree;
|
|
case "rearWiperApplicableForTierThree":
|
|
return this.rearWiperApplicableForTierThree;
|
|
case "rainDefenseApplicableForTierThree":
|
|
return this.rainDefenseApplicableForTierThree;
|
|
default:
|
|
return null;
|
|
}
|
|
},
|
|
},
|
|
components: {
|
|
buttonQuestion,
|
|
},
|
|
};
|
|
</script>
|