Merge branch 'develop' into feature/CSR-1600

This commit is contained in:
CarlNation 2024-09-26 12:00:18 -04:00
commit 63880eb135
11 changed files with 171 additions and 37 deletions

View file

@ -12,6 +12,8 @@ const GaEvents = {
const GaCategories = { const GaCategories = {
API_RESPONSE: "Api_Response", API_RESPONSE: "Api_Response",
EVOX: "Evox", EVOX: "Evox",
APPOINTMENT: "Appointment",
SERVICE_LOCATION: "service-location",
}; };
const GaActions = { const GaActions = {
@ -21,6 +23,10 @@ const GaActions = {
SUBMITTED: "Submitted", SUBMITTED: "Submitted",
DISPLAYED: "Displayed", DISPLAYED: "Displayed",
CASH_QUOTE_DISPLAYED: "Cash quote displayed", CASH_QUOTE_DISPLAYED: "Cash quote displayed",
SERVICE_PACKAGE_PRICE: "Service package price",
MOBILE_AVAILABLE: "mobile_available",
SHOPS_FIRST_DISPLAYED: "shops_first_displayed",
MORE_LOCATIONS_CLICKED: "more_locations_clicked",
}; };
const GaLabels = { const GaLabels = {
@ -29,6 +35,8 @@ const GaLabels = {
LICENSE_PLATE_LOOKUP: "License_Plate_Look_Up", LICENSE_PLATE_LOOKUP: "License_Plate_Look_Up",
VIN_LOOKUP: "Vin_Look_Up", VIN_LOOKUP: "Vin_Look_Up",
ADDRESS_LOOKUP: "Address_Look_up", ADDRESS_LOOKUP: "Address_Look_up",
YES: "yes",
NO: "no",
}; };
const ValueToLogTypes = { const ValueToLogTypes = {

View file

@ -4,5 +4,5 @@ export const headerKeys = {
REFERRAL_SEQUENCE_NUMBER: "X-Referral-Sequence-Number", REFERRAL_SEQUENCE_NUMBER: "X-Referral-Sequence-Number",
SESSION_SEQUENCE_NUMBER: "X-Session-Sequence-Number", SESSION_SEQUENCE_NUMBER: "X-Session-Sequence-Number",
TRANSACTION_ID: "X-Transaction-Id", TRANSACTION_ID: "X-Transaction-Id",
EON: "X-EON", EON: "X-Enterprise-Order-Number",
}; };

View file

@ -93,7 +93,6 @@ import textBlock from "@/digital-components/text-block/text-block";
//Supporting files //Supporting files
import baseMixin from "@/mixins/base-mixin.js"; import baseMixin from "@/mixins/base-mixin.js";
import analyticsMixin from "@/mixins/analytics-mixin";
import store from "@/store"; import store from "@/store";
import { storeActions } from "@/constants/store-actions"; import { storeActions } from "@/constants/store-actions";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
@ -107,7 +106,8 @@ import { get12HourTimeFormat, get12HourTimeMobileFormat } from "@/helpers/date-h
import { coverageStatus } from "@/constants/insurance"; import { coverageStatus } from "@/constants/insurance";
import { getDisplayTextForDurationLength } from "@/helpers/duration-length-helper"; import { getDisplayTextForDurationLength } from "@/helpers/duration-length-helper";
import { experimentSettings } from "@/constants/experiments"; import { experimentSettings } from "@/constants/experiments";
import experimentMixin from "@/mixins/experiment-mixin.js"; import { partTypeStrings } from "@/constants/part-type-strings";
import { containsLineItemWithPartType } from "@/helpers/service-package-helper";
export default { export default {
name: "confirmation", name: "confirmation",
@ -169,8 +169,17 @@ export default {
}; };
}, },
computed: { computed: {
isRecalibrationOnOrder() {
return containsLineItemWithPartType(
partTypeStrings.RECALIBRATION,
this?.lineItems?.supportingItems
);
},
shouldHideRecalibration() { shouldHideRecalibration() {
return this.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE); return (
this.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE)?.toLowerCase() ===
"true" && this.isRecalibrationOnOrder
);
}, },
ShowCart() { ShowCart() {
if (this.isPia && this.submittedOrder?.settledTenderAmount == 0) { if (this.isPia && this.submittedOrder?.settledTenderAmount == 0) {

View file

@ -593,8 +593,8 @@ export default {
}, },
shouldHideRecalibration() { shouldHideRecalibration() {
return ( return (
this.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE).toLowerCase() === "true" && this.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE)?.toLowerCase() ===
this.isRecalibrationOnOrder "true" && this.isRecalibrationOnOrder
); );
}, },
showApplePay() { showApplePay() {

View file

@ -7,6 +7,7 @@ import store from "@/store";
import * as navigateToHeritage from "@/helpers/heritage-integration/navigation-helper"; import * as navigateToHeritage from "@/helpers/heritage-integration/navigation-helper";
import { nextTick } from "vue"; import { nextTick } from "vue";
import { experimentSettings } from "@/constants/experiments"; import { experimentSettings } from "@/constants/experiments";
import experimentMixin from "@/mixins/experiment-mixin.js";
import baseMixin from "@/mixins/base-mixin.js"; import baseMixin from "@/mixins/base-mixin.js";
import { containsLineItemWithPartType } from "../../helpers/service-package-helper"; import { containsLineItemWithPartType } from "../../helpers/service-package-helper";
@ -746,6 +747,14 @@ function setupMocks({ customMountOptions }) {
...customMountOptions, ...customMountOptions,
}); });
mountOptions.mixins = [
{
methods: {
getSettingValue: jest.fn(),
},
},
];
baseMixin.methods.ResetExternalParamsAndHideModal = jest.fn(); baseMixin.methods.ResetExternalParamsAndHideModal = jest.fn();
baseMixin.methods.isFormValid = jest.fn().mockReturnValue(true); baseMixin.methods.isFormValid = jest.fn().mockReturnValue(true);
mountOptions.global.mocks["$store"] = store; mountOptions.global.mocks["$store"] = store;

View file

@ -113,8 +113,7 @@ import { storeActions } from "@/constants/store-actions";
import { deepClone } from "@/helpers/object-helper"; import { deepClone } from "@/helpers/object-helper";
import store from "@/store"; import store from "@/store";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { experimentUniverses, experimentSettings } from "@/constants/experiments"; import { experimentSettings } from "@/constants/experiments";
import { getSessionKeyValue, getUserIdValue } from "@/helpers/heritage-integration/cookie-helper";
import { required } from "@/helpers/validation-rules"; import { required } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages"; import { errorMessages } from "@/constants/error-messages";
import { Form, defineRule } from "vee-validate"; import { Form, defineRule } from "vee-validate";
@ -129,7 +128,10 @@ import { queryStrings } from "@/constants/query-strings";
import { getQuerystringParameter } from "@/helpers/querystring-helper"; import { getQuerystringParameter } from "@/helpers/querystring-helper";
import promoModalQuestion from "@/fmg-components/promo-modal-question/promo-modal-question"; import promoModalQuestion from "@/fmg-components/promo-modal-question/promo-modal-question";
import { partTypeStrings } from "@/constants/part-type-strings"; import { partTypeStrings } from "@/constants/part-type-strings";
import { containsLineItemWithPartType } from "@/helpers/service-package-helper"; import {
containsLineItemWithPartType,
findLineItemsWithPartType,
} from "@/helpers/service-package-helper";
import { nextTick } from "vue"; import { nextTick } from "vue";
import { packageNames } from "@/constants/package-names"; import { packageNames } from "@/constants/package-names";
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
@ -296,8 +298,12 @@ export default {
const serviceLocationState = store.getters.order.serviceLocation.state; const serviceLocationState = store.getters.order.serviceLocation.state;
// Override if coming back from QuoteDetails. Remove override after Quote release // Override if coming back from QuoteDetails. Remove override after Quote release
const isInsuranceOverrideValue = to.query?.isInsurance; const isInsuranceOverrideValue = to.query?.isInsurance;
const defaultIsInsuranceSelectedValue = store.getters.order.payment.isInsurance; const defaultIsInsuranceSelectedValue = store.getters.order.payment.isInsurance;
const hideRecalCost =
experimentMixin.methods
.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE)
?.toLowerCase() === "true";
//Default to Insurance Tab if user Service zip is from certain States //Default to Insurance Tab if user Service zip is from certain States
if ( if (
serviceLocationState != null && serviceLocationState != null &&
@ -309,15 +315,17 @@ export default {
} else if (defaultIsInsuranceSelectedValue != null) { } else if (defaultIsInsuranceSelectedValue != null) {
return defaultIsInsuranceSelectedValue; return defaultIsInsuranceSelectedValue;
} else { } else {
// TEMPORARY CODE WHILE DEVELOPING
if (availableLineItems) { if (availableLineItems) {
let tierOnePackagePriceTemp = baseMixin.methods.getTierOnePackagePrice( const lineItemsForCalculatingPrice = hideRecalCost
baseMixin.methods.filterOutFees(availableLineItems) ? baseMixin.methods.filterOutFees(
); baseMixin.methods.filterOutRecalibration(availableLineItems) // Strip out recal before filtering out fees
let whatToReturn = baseMixin.methods.getTierOnePackagePrice( )
baseMixin.methods.filterOutFees(availableLineItems) : baseMixin.methods.filterOutFees(availableLineItems);
) > insuranceThreshold;
return whatToReturn; // TODO AJC: TIGHTEN THIS BACK UP AFTER TESTING return (
baseMixin.methods.getTierOnePackagePrice(lineItemsForCalculatingPrice) >
insuranceThreshold
); // compare base price vs arbitrary threshold (representing insurance price)
} else { } else {
return null; return null;
} }
@ -328,15 +336,20 @@ export default {
experimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL experimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL
); );
if (!store.getters.externalParameterState?.isExternalParameter) { // there are no external parameters if (!store.getters.externalParameterState?.isExternalParameter) {
// there are no external parameters
if (internalThreshold) thresholdToUse = internalThreshold; if (internalThreshold) thresholdToUse = internalThreshold;
vm.isInsuranceSelected = getIsInsuranceSelectedValue(vm.availableLineItems, thresholdToUse); vm.isInsuranceSelected = getIsInsuranceSelectedValue(
vm.availableLineItems,
thresholdToUse
);
baseMixin.methods.ResetExternalParamsAndHideModal(); baseMixin.methods.ResetExternalParamsAndHideModal();
} else {
// there ARE external parameters
} else { // there ARE external parameters if (store.getters.externalParameterQuote.isInsurance == true) {
// did user intentionally select insurance?
if (store.getters.externalParameterQuote.isInsurance == true) { // did user intentionally select insurance?
vm.isInsuranceSelected = true; vm.isInsuranceSelected = true;
vm.servicePackage = store.getters.externalParameterQuote.servicePackage; vm.servicePackage = store.getters.externalParameterQuote.servicePackage;
await nextTick(); await nextTick();
@ -348,7 +361,9 @@ export default {
} }
} else { } else {
// did user come from external source (LeadGen)? // did user come from external source (LeadGen)?
let externalSource = store.getters.externalParameterSource ? store.getters.externalParameterSource : null; let externalSource = store.getters.externalParameterSource
? store.getters.externalParameterSource
: null;
// Business logic to determine what "external" source is // Business logic to determine what "external" source is
if (externalSource?.includes("LeadGen")) { if (externalSource?.includes("LeadGen")) {
@ -359,10 +374,12 @@ export default {
} else { } else {
if (internalThreshold) thresholdToUse = internalThreshold; if (internalThreshold) thresholdToUse = internalThreshold;
} }
vm.isInsuranceSelected = getIsInsuranceSelectedValue(vm.availableLineItems, thresholdToUse); vm.isInsuranceSelected = getIsInsuranceSelectedValue(
vm.availableLineItems,
thresholdToUse
);
baseMixin.methods.ResetExternalParamsAndHideModal(); baseMixin.methods.ResetExternalParamsAndHideModal();
} }
} }
}); });
}, },
@ -387,11 +404,23 @@ export default {
this?.availableLineItems this?.availableLineItems
); );
}, },
shouldHideRecalibration() { isServicePackageDiscountOnOrder() {
const recalSettingValue = experimentMixin.methods.getSettingValue( return containsLineItemWithPartType(
experimentSettings.RECAL_PRICE_REMOVE partTypeStrings.SERVICE_PACKAGE_DISCOUNT,
this.availableLineItems
);
},
servicePackageDiscountParts() {
return findLineItemsWithPartType(
partTypeStrings.SERVICE_PACKAGE_DISCOUNT,
this.availableLineItems
);
},
shouldHideRecalibration() {
return (
this.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE)?.toLowerCase() ===
"true" && this.isRecalibrationOnOrder
); );
return recalSettingValue;
}, },
showAfterpayBanner() { showAfterpayBanner() {
return ( return (
@ -549,6 +578,46 @@ export default {
); );
} }
}); });
this.$nextTick(() => {
const availablePackageNames = this.$refs.servicePackage.servicePackageAnswers;
var eventLabel = "";
availablePackageNames?.forEach((tier) => {
if (tier) {
let lineItemsToPrice = this.availableLineItems;
if (this.isRecalibrationOnOrder && this.shouldHideRecalibration) {
lineItemsToPrice = lineItemsToPrice?.filter((item) => {
return item.partType != partTypeStrings.RECALIBRATION;
});
}
if (this.isServicePackageDiscountOnOrder) {
lineItemsToPrice = lineItemsToPrice?.filter((item) => {
return (
item.partType != this.servicePackageDiscountParts[0].partType
);
});
}
let price = 0;
if (tier.value == "TierTwo" && this.isServicePackageDiscountOnOrder) {
lineItemsToPrice.push(...this.servicePackageDiscountParts);
}
price += baseMixin.methods.getTierOnePackagePrice(
baseMixin.methods.filterOutFees(lineItemsToPrice)
);
price += this.$refs.servicePackage.getVapsPrice(tier.value);
const formattedPrice = parseFloat(price).toFixed(2);
eventLabel += tier.value + "_" + formattedPrice;
}
eventLabel += ",";
});
eventLabel = eventLabel.slice(0, -1);
this.pushEventToGA(
"quote",
this.GaActions.SERVICE_PACKAGE_PRICE,
eventLabel,
true
);
});
}, },
}, },
mounted() { mounted() {

View file

@ -15,7 +15,6 @@
import buttonQuestion from "@/digital-components/button-question/button-question"; import buttonQuestion from "@/digital-components/button-question/button-question";
import baseMixin from "@/mixins/base-mixin.js"; import baseMixin from "@/mixins/base-mixin.js";
import { processIfStatements } from "@/helpers/cms-content-helper"; 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 servicePackageRadio from "./service-package-radio/service-package-radio";
import { partTypeStrings } from "@/constants/part-type-strings"; import { partTypeStrings } from "@/constants/part-type-strings";
import { packageNames } from "@/constants/package-names"; import { packageNames } from "@/constants/package-names";
@ -237,7 +236,7 @@ export default {
return (this.isInsuranceSelected ? "As little as $" : "$") + formattedPriceFloat; return (this.isInsuranceSelected ? "As little as $" : "$") + formattedPriceFloat;
}, },
getPackagePrice(packageName, { discountedPrice = false, servicePackageDiscount = false }) { getPackagePrice(packageName, { discountedPrice = false, servicePackageDiscount = false }) {
var lineItemsToPrice = [...this.nullSafeAvailableLineItems]; let lineItemsToPrice = [...this.nullSafeAvailableLineItems];
if (this.isRecalibrationOnOrder && this.shouldHideRecalibration) { if (this.isRecalibrationOnOrder && this.shouldHideRecalibration) {
lineItemsToPrice = lineItemsToPrice.filter((item) => { lineItemsToPrice = lineItemsToPrice.filter((item) => {

View file

@ -433,6 +433,18 @@ export default {
if (shopProviderData) { if (shopProviderData) {
this.shopProviderData = shopProviderData; this.shopProviderData = shopProviderData;
} }
var gaLabel = this.GaLabels.NO;
if (this.isServiceableMobile) {
gaLabel = this.GaLabels.YES;
}
this.pushEventToGA(
this.GaCategories.APPOINTMENT,
this.GaActions.MOBILE_AVAILABLE,
gaLabel,
true
);
}, },
setContainsMilitaryBase(val) { setContainsMilitaryBase(val) {
if (this.zipContainsMilitaryBase !== val) { if (this.zipContainsMilitaryBase !== val) {
@ -607,7 +619,7 @@ export default {
}, },
false false
); );
console.log(this.billToAccountNumber);
if (this.billToAccountNumber) { if (this.billToAccountNumber) {
this.dispatchStoreAction( this.dispatchStoreAction(
this.storeActions.SAVE_BILL_TO_ACCOUNT_NUMBER, this.storeActions.SAVE_BILL_TO_ACCOUNT_NUMBER,

View file

@ -52,6 +52,7 @@ import { nextTick } from "vue";
import { getAvailabilityRating } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper"; import { getAvailabilityRating } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper";
import { Provider } from "@/layouts/service-location/classes/provider"; import { Provider } from "@/layouts/service-location/classes/provider";
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
defineRule("option-required", required(errorMessages.OPTION_REQUIRED)); defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
@ -125,6 +126,8 @@ export default {
}, },
methods: { methods: {
async getNextShopsFromList(numberToGet = 3) { async getNextShopsFromList(numberToGet = 3) {
const logFirstShopsDisplayed = this.shopIndex == 0;
const shopIterator = (array, n) => { const shopIterator = (array, n) => {
const l = array.length; const l = array.length;
return () => { return () => {
@ -160,6 +163,27 @@ export default {
}; };
}); });
var gaAction = this.GaActions.MORE_LOCATIONS_CLICKED;
if (logFirstShopsDisplayed) {
gaAction = this.GaActions.SHOPS_FIRST_DISPLAYED;
}
if (this.selectedAppointmentType === AppointmentTypeStrings.IN_SHOP) {
var shops = mappedData.map((shop) => {
if (shop.value.length > 5 && shop.value.startsWith("00")) {
return shop.value.substring(1);
} else {
return shop.value;
}
});
this.pushEventToGA(
this.GaCategories.SERVICE_LOCATION,
gaAction,
shops.join("/"),
true
);
}
if (this.answers.length === 0) { if (this.answers.length === 0) {
this.answers = mappedData; this.answers = mappedData;
} else { } else {

View file

@ -211,6 +211,13 @@ export default {
payload.glassToReplace = glassString; payload.glassToReplace = glassString;
} }
//EON
if (order.eon) {
payload.eon = order.eon;
} else {
payload.eon = "";
}
// Work Order Id // Work Order Id
if (order.workOrderId) { if (order.workOrderId) {
const parsedId = parseInt(order.workOrderId); const parsedId = parseInt(order.workOrderId);

View file

@ -1537,12 +1537,9 @@ export const actions = {
? context.getters.payment.billToAccountNumber ? context.getters.payment.billToAccountNumber
: applicationConfig.CASH_DEFAULT_BILL_TO_ACCOUNT_NUMBER; : applicationConfig.CASH_DEFAULT_BILL_TO_ACCOUNT_NUMBER;
const covStatus = context.getters.payment?.insuranceCoverage?.coverageStatus;
const covSubStatus = context.getters.payment?.insuranceCoverage?.coverageSubStatus;
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
method: endpoints.GetMobileFeePart.method, method: endpoints.GetMobileFeePart.method,
endpoint: `${endpoints.GetMobileFeePart.url}/${damageType}/${parentAccountNumber}/${billToAccountNumber}/${covStatus}/${covSubStatus}`, endpoint: `${endpoints.GetMobileFeePart.url}/${damageType}/${parentAccountNumber}/${billToAccountNumber}`,
logApiCall: true, logApiCall: true,
pageNameToLog: pageNameToLog, pageNameToLog: pageNameToLog,
}); });