diff --git a/public/static/healthcheck/index.html b/public/static/healthcheck/index.html
index 9e20bde78..52e21bb5b 100644
--- a/public/static/healthcheck/index.html
+++ b/public/static/healthcheck/index.html
@@ -509,7 +509,7 @@
'AccountService': {
baseUrl: apiUrl + '/account/api/v1',
endpoints: [
- //{ path: '/healthcheck', method: 'GET' },
+ { path: '/healthcheck', method: 'GET' },
{ path: '/account/insurance-companies', method: 'GET' },
{ path: '/account/account-details/373341', method: 'GET' },
{ path: '/account/bill-to-account-number?ParentAccountNumber=373341&ProviderNumber=01820&IsItac=false&TypeOfClaim=Personal&LineOfBusiness=Commercial', method: 'GET' }
@@ -518,7 +518,7 @@
'LocationService': {
baseUrl: apiUrl + '/location/api/v1',
endpoints: [
- //{ path: '/healthcheck', method: 'GET' },
+ { path: '/healthcheck', method: 'GET' },
{ path: '/location/zip/43015/Replace', method: 'GET' },
{ path: '/location/alert-reasons/03357', method: 'GET' },
{ path: '/location/providers/43015/Replace/100/167132/true/CR00046193/false', method: 'GET' },
@@ -528,7 +528,7 @@
'VehicleService': {
baseUrl: apiUrl + '/vehicle/api/v1',
endpoints: [
- //{ path: '/healthcheck', method: 'GET' },
+ { path: '/healthcheck', method: 'GET' },
{ path: '/vehicle/years', method: 'GET' },
{ path: '/vehicle/makes/1997', method: 'GET' },
{ path: '/vehicle/Models/1997/Toyota', method: 'GET' },
@@ -539,7 +539,7 @@
'PartService': {
baseUrl: apiUrl + '/parts/api/v1',
endpoints: [
- //{ path: '/healthcheck', method: 'GET' },
+ { path: '/healthcheck', method: 'GET' },
{ path: '/parts/damage-options/CR00046193', method: 'GET' },
{ path: '/parts/rain-repel', method: 'GET' },
{ path: '/parts/parts-or-questions', method: 'POST', body: {"carId":"CR00046193","glassPieces":[{"location":"Windshield","name":"Single"}],"zip":"43015","vin":null,"serviceType":null,"referralSeqNumber":environmentContext.referralNumber,"AppName":"FixMyGlass"} },
@@ -553,7 +553,7 @@
'PriceService': {
baseUrl: apiUrl + '/price/api/v1',
endpoints: [
- //{ path: '/healthcheck', method: 'GET' },
+ { path: '/healthcheck', method: 'GET' },
{ path: '/price/taxed-order-items?ParentAccountNumber=167132&BillToAccountNumber=87291&ProviderNumber=003357&AppointmentType=Mobile&ServiceLocation.City=asdf&ServiceLocation.State=OH&ServiceLocation.ZipCode=43015&lineItems[0].partNumber=FW02018GBNN&lineItems[0].laborAmount=60&lineItems[0].kitPrice=0&lineItems[0].sellingPrice=297.33&lineItems[1].partNumber=GGG%202018&lineItems[1].laborAmount=0&lineItems[1].kitPrice=0&lineItems[1].sellingPrice=13.4&lineItems[2].partNumber=RECYCLE%20FEE&lineItems[2].laborAmount=39.99&lineItems[2].kitPrice=0&lineItems[2].sellingPrice=0&ServerData=' + encodeURIComponent(environmentContext.serverData), method: 'GET' },
{ path: '/price/order-items', method: 'POST', body: { "parentAccountNumber": 167132, "billToAccountNumber": "87291", "providerNumber": "03357", "carId": "CR00046193", "year": 1997, "make": "Toyota", "model": "Camry", "eon": environmentContext.eon, "state": "OH", "referralNumber": environmentContext.referralNumber, "referralSequenceNumber": environmentContext.referralNumber, "zipCode": "43015", "serviceZipCode": "43015", "referralDate": "2025-10-29T10:55:27.18", "isReplacement": true, "deductible": 0, "coverageStatus": null, "lineItems": [ { "partNumber": "RECYCLE FEE" }, { "partNumber": "FW02018GBNN" }, { "partNumber": "GGG 2018" }, { "partNumber": "SBB19" }, { "partNumber": "SBB21" } ], "serverData": "", "AppName": "FixMyGlass" } },
{ path: '/price/order-promo', method: 'POST', body: {"promoCode":"WEBSL45","addableVaps":[{"partNumber":"RAIN REPEL","description":null,"partType":"RAIN REPEL","isInsurable":null,"id":"ccb0865d-1c0a-4be7-8605-bc7b9cb3d221","isChildPart":false,"laborAmount":0,"sellingPrice":44.99,"kitPrice":0,"salesTax":null},{"partNumber":"SBB19","description":"SAFELITE BEAM BLADE 19","partType":"FRONT WIPER","isInsurable":null,"id":"4db19a8b-739f-4f7b-983e-f6308c5f5901","isChildPart":false,"laborAmount":0,"sellingPrice":34.99,"kitPrice":0,"salesTax":null},{"partNumber":"SBB21","description":"SAFELITE BEAM BLADE 21","partType":"FRONT WIPER","isInsurable":null,"id":"e27ae20a-3a60-4fdf-a738-4b56d2e761cb","isChildPart":false,"laborAmount":0,"sellingPrice":34.99,"kitPrice":0,"salesTax":null}],"order":{"appointmentType":"Mobile","carId":"CR00046193","correlationId":"b0261e48-1111-44fc-abc9-34b41380687c","eon":environmentContext.eon,"isInsurance":false,"isRepair":false,"glassToReplace":[{"location":"Windshield","name":"Single"}],"lineItemsOnOrder":[{"partNumber":"FW02018GBNN","basePartNumber":"FW02018","description":"solar","color":"Green Tint, Blue Shade","partType":"WINDSHIELD","canSafeliteRecalibrate":false,"requiresRecalibration":false,"requiresCapabilityQuestions":false,"recalibrationType":null,"childParts":[{"partNumber":"GGG 2018","safelitePartNumber":"GGG 2018","id":"329cf0ec-8106-4e62-ab66-de0da8f18a1d","isChildPart":true,"laborAmount":0,"sellingPrice":13.4,"kitPrice":0,"salesTax":0.94}],"kitPrice":0,"sellingPrice":368.94,"laborAmount":60,"id":"4326cee6-b39e-41ff-bb29-df9220e32298","isChildPart":false,"salesTax":30.02},{"partNumber":"GGG 2018","safelitePartNumber":"GGG 2018","id":"329cf0ec-8106-4e62-ab66-de0da8f18a1d","isChildPart":true,"laborAmount":0,"sellingPrice":13.4,"kitPrice":0,"salesTax":0.94},{"partNumber":"RECYCLE FEE","description":null,"partType":"REPLACE FEE","isInsurable":null,"isChildPart":false,"laborAmount":39.99,"sellingPrice":0,"kitPrice":0,"salesTax":2.8,"id":"3771aed5-0de1-4f0e-b1ad-394f73e08f38","cartItemType":"REPLACE FEE"},{"partNumber":"MOBILE FEE","description":null,"partType":"MOBILE FEE","isInsurable":true,"isChildPart":false,"laborAmount":0,"sellingPrice":0,"kitPrice":0,"salesTax":0,"id":"2bc936ec-ef5e-4fe2-95fb-e946792b1ae5"},{"partNumber":"SBB19","description":"SAFELITE BEAM BLADE 19","partType":"FRONT WIPER","isInsurable":null,"id":"4db19a8b-739f-4f7b-983e-f6308c5f5901","isChildPart":false,"laborAmount":0,"sellingPrice":34.99,"kitPrice":0,"salesTax":2.45,"cartItemType":"FRONT WIPERS"},{"partNumber":"SBB21","description":"SAFELITE BEAM BLADE 21","partType":"FRONT WIPER","isInsurable":null,"id":"e27ae20a-3a60-4fdf-a738-4b56d2e761cb","isChildPart":false,"laborAmount":0,"sellingPrice":34.99,"kitPrice":0,"salesTax":2.45,"cartItemType":"FRONT WIPERS"},{"partNumber":"RAIN REPEL","description":null,"partType":"RAIN REPEL","isInsurable":null,"id":"ccb0865d-1c0a-4be7-8605-bc7b9cb3d221","isChildPart":false,"laborAmount":0,"sellingPrice":44.99,"kitPrice":0,"salesTax":3.15,"cartItemType":"RAIN REPEL"}],"parentAccountNumber":"167132","referralSequenceNumber":environmentContext.referralNumber,"serviceState":"OH","serverData":environmentContext.serverData,"vehicleYear":"1997","zipCodeOrProviderCtu":"03357"},"AppName":"FixMyGlass"} },
@@ -563,7 +563,7 @@
'ScheduleService': {
baseUrl: apiUrl + '/schedule/api/v1',
endpoints: [
- //{ path: '/healthcheck', method: 'GET' },
+ { path: '/healthcheck', method: 'GET' },
{ path: '/schedule/mobile-time-slots', method: 'POST', body: {"startDate":startDate,"endDate":endDate,"applicationName":"FixMyGlass","parentAccountNumber":"167132","carId":"CR00046193","lineItems":[{"partNumber":"RECYCLE FEE","partType":"REPLACE FEE","isGlassPart":false},{"partNumber":"SBB19","partType":"FRONT WIPER","isGlassPart":false},{"partNumber":"SBB21","partType":"FRONT WIPER","isGlassPart":false},{"partNumber":"RAIN REPEL","partType":"RAIN REPEL","isGlassPart":false},{"partNumber":"FW02018GBNN","partType":"WINDSHIELD","isGlassPart":true},{"partNumber":"GGG 2018","isGlassPart":false}],"glassPieces":[{"location":"Windshield","name":"Single"}],"eon":environmentContext.eon,"billToAccountNumber":"87291","coverage":{"status":null,"deductible":0,"additionalAuthFlag":null},"partSelection":{"hasAnsweredPartQuestions":false,"hasAnsweredMoldingQuestions":false,"hasAnsweredCapabilityQuestions":false,"hasManuallySelectedParts":false},"vehicle":{"year":1997,"make":"Toyota","model":"Camry","style":"4 door sedan","vin":""},"zipCode":"43015","AppName":"FixMyGlass"} },
{ path: '/schedule/shop-time-slots', method: 'POST', body: {"providerNumber":"003417","startDate":startDate,"endDate":endDate,"shopAppointmentType":"InshopOrDropoff","applicationName":"FixMyGlass","parentAccountNumber":"167132","carId":"CR00046193","lineItems":[{"partNumber":"RECYCLE FEE","partType":"REPLACE FEE","isGlassPart":false},{"partNumber":"FW02018GBNN","partType":"WINDSHIELD","isGlassPart":true},{"partNumber":"GGG 2018","isGlassPart":false}],"glassPieces":[{"location":"Windshield","name":"Single"}],"eon":environmentContext.eon,"billToAccountNumber":"87291","coverage":{"status":null,"deductible":0,"additionalAuthFlag":null},"partSelection":{"hasAnsweredPartQuestions":false,"hasAnsweredMoldingQuestions":false,"hasAnsweredCapabilityQuestions":false,"hasManuallySelectedParts":false},"vehicle":{"year":1997,"make":"Toyota","model":"Camry","style":"4 door sedan","vin":""},"AppName":"FixMyGlass"} }
]
@@ -571,25 +571,25 @@
'AnalyticsService': {
baseUrl: apiUrl + '/analytics/api/v1',
endpoints: [
- //{ path: '/healthcheck', method: 'GET' },
+ { path: '/healthcheck', method: 'GET' },
]
},
'ExperimentService': {
baseUrl: apiUrl + '/experiments/api/v1',
endpoints: [
- //{ path: '/healthcheck', method: 'GET' },
+ { path: '/healthcheck', method: 'GET' },
]
},
'OrderService': {
baseUrl: apiUrl + '/order/api/v1',
endpoints: [
- //{ path: '/healthcheck', method: 'GET' },
+ { path: '/healthcheck', method: 'GET' },
]
},
'ContentService': {
baseUrl: apiUrl + '/content/api/v1',
endpoints: [
- //{ path: '/healthcheck', method: 'GET' },
+ { path: '/healthcheck', method: 'GET' },
{ path: '/content/fmg/vehicle', method: 'GET' },
]
}
@@ -674,7 +674,7 @@
}
function updateAtAGlanceText() {
- const healthyCount = Object.values(healthData).filter(service => service.status === 'healthy').length;
+ const healthyCount = Object.values(healthData).filter(service => (service.status === 'healthy' || service.status === 'degraded')).length;
const totalCount = Object.values(healthData).length;
let text = 'Healthy';
let className = 'stat-pill stat-pill-healthy';
@@ -763,14 +763,15 @@
// Determine overall service status
const endpoints = healthData[serviceName].endpoints;
const healthyCount = endpoints.filter(ep => !isDegraded(ep) && !isUnhealthy(ep)).length;
+ const unhealthyCount = endpoints.filter(ep => isUnhealthy(ep)).length;
const totalCount = endpoints.length;
if (healthyCount === totalCount) {
healthData[serviceName].status = 'healthy';
- } else if (healthyCount > 0) {
- healthData[serviceName].status = 'degraded';
- } else {
+ } else if (unhealthyCount > 0) {
healthData[serviceName].status = 'unhealthy';
+ } else {
+ healthData[serviceName].status = 'degraded';
}
}
diff --git a/src/constants/cart-item-categories.js b/src/constants/cart-item-categories.js
index 5c8faafcf..6bbb960b9 100644
--- a/src/constants/cart-item-categories.js
+++ b/src/constants/cart-item-categories.js
@@ -3,7 +3,7 @@ const cartItemCategories = {
GLASS_PARTS: "glassParts",
SUPPORTING_ITEMS: "supportingItems",
PROMOS: "promos",
- QUOTE_PAGE_DISCOUNT: "quotePageDiscount",
+ SERVICE_PACKAGE_DISCOUNT: "servicePackageDiscount",
};
export { cartItemCategories };
diff --git a/src/constants/cart-item-types.js b/src/constants/cart-item-types.js
index 8f70aeaed..0bb418d43 100644
--- a/src/constants/cart-item-types.js
+++ b/src/constants/cart-item-types.js
@@ -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",
};
diff --git a/src/constants/part-type-strings.js b/src/constants/part-type-strings.js
index 17b96d2fb..741132e28 100644
--- a/src/constants/part-type-strings.js
+++ b/src/constants/part-type-strings.js
@@ -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",
};
diff --git a/src/constants/quote-page-discounts.js b/src/constants/quote-page-discounts.js
deleted file mode 100644
index 2dd32d915..000000000
--- a/src/constants/quote-page-discounts.js
+++ /dev/null
@@ -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,
- },
-];
diff --git a/src/experiment-components/service-package-radio-for-afterpay.vue b/src/experiment-components/service-package-radio-for-afterpay.vue
index 7f7e91084..2e746e4f2 100644
--- a/src/experiment-components/service-package-radio-for-afterpay.vue
+++ b/src/experiment-components/service-package-radio-for-afterpay.vue
@@ -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
+ );
},
},
};
diff --git a/src/experiment-components/service-package-radio.vue b/src/experiment-components/service-package-radio.vue
index a116fecd8..ee7e12712 100644
--- a/src/experiment-components/service-package-radio.vue
+++ b/src/experiment-components/service-package-radio.vue
@@ -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">
-
+
diff --git a/src/fmg-components/cart/cart.vue b/src/fmg-components/cart/cart.vue
index e890e53cc..d1bd2a939 100644
--- a/src/fmg-components/cart/cart.vue
+++ b/src/fmg-components/cart/cart.vue
@@ -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 =
diff --git a/src/layouts/quote/quote.spec.js b/src/layouts/quote/quote.spec.js
index 5d9f3bacb..aea32211e 100644
--- a/src/layouts/quote/quote.spec.js
+++ b/src/layouts/quote/quote.spec.js
@@ -82,7 +82,7 @@ jest.mock("@/mixins/base-mixin", () => ({
filterOutFees(items) {
return null;
},
- filterOutQuotePageDiscountPart(items) {
+ filterOutServicePackageDiscountPart(items) {
return null;
},
isFormValid(form) {
diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue
index 17326ec8e..7f9ea7efc 100644
--- a/src/layouts/quote/quote.vue
+++ b/src/layouts/quote/quote.vue
@@ -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 />
@@ -175,7 +174,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));
@@ -186,14 +184,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) {
@@ -310,22 +300,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
@@ -352,7 +349,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,
@@ -454,9 +451,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") {
@@ -580,8 +578,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 (
@@ -610,23 +617,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() {
@@ -670,7 +660,7 @@ export default {
vapsItemsSelectedAction(vapsItemsSelected) {
this.lineItems.vaps = vapsItemsSelected;
},
- quotePageDiscountSelectedAction(supportingItemsSelected) {
+ servicePackageDiscountSelectedAction(supportingItemsSelected) {
this.lineItems.supportingItems = supportingItemsSelected;
},
backButtonAction() {
@@ -732,10 +722,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,
@@ -821,23 +811,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)
diff --git a/src/layouts/quote/service-package-question/service-package-question.spec.js b/src/layouts/quote/service-package-question/service-package-question.spec.js
index a44dc463c..523c0edce 100644
--- a/src/layouts/quote/service-package-question/service-package-question.spec.js
+++ b/src/layouts/quote/service-package-question/service-package-question.spec.js
@@ -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
diff --git a/src/layouts/quote/service-package-question/service-package-question.vue b/src/layouts/quote/service-package-question/service-package-question.vue
index e45147295..d1a99da08 100644
--- a/src/layouts/quote/service-package-question/service-package-question.vue
+++ b/src/layouts/quote/service-package-question/service-package-question.vue
@@ -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];
diff --git a/src/layouts/quote/service-package-question/service-package-radio/service-package-radio.vue b/src/layouts/quote/service-package-question/service-package-radio/service-package-radio.vue
index 8bb7e921a..441a4f5cb 100644
--- a/src/layouts/quote/service-package-question/service-package-radio/service-package-radio.vue
+++ b/src/layouts/quote/service-package-question/service-package-radio/service-package-radio.vue
@@ -5,7 +5,7 @@
:class="[this.buttonLabelSubCopy ? 'has-subheader' : '']"
for="testradio">
-
+
diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js
index 813a3189a..5204178de 100644
--- a/src/mixins/base-mixin.js
+++ b/src/mixins/base-mixin.js
@@ -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;
},