Merge branch 'develop' into feature/CSR-1600
This commit is contained in:
commit
63880eb135
11 changed files with 171 additions and 37 deletions
|
|
@ -12,6 +12,8 @@ const GaEvents = {
|
|||
const GaCategories = {
|
||||
API_RESPONSE: "Api_Response",
|
||||
EVOX: "Evox",
|
||||
APPOINTMENT: "Appointment",
|
||||
SERVICE_LOCATION: "service-location",
|
||||
};
|
||||
|
||||
const GaActions = {
|
||||
|
|
@ -21,6 +23,10 @@ const GaActions = {
|
|||
SUBMITTED: "Submitted",
|
||||
DISPLAYED: "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 = {
|
||||
|
|
@ -29,6 +35,8 @@ const GaLabels = {
|
|||
LICENSE_PLATE_LOOKUP: "License_Plate_Look_Up",
|
||||
VIN_LOOKUP: "Vin_Look_Up",
|
||||
ADDRESS_LOOKUP: "Address_Look_up",
|
||||
YES: "yes",
|
||||
NO: "no",
|
||||
};
|
||||
|
||||
const ValueToLogTypes = {
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ export const headerKeys = {
|
|||
REFERRAL_SEQUENCE_NUMBER: "X-Referral-Sequence-Number",
|
||||
SESSION_SEQUENCE_NUMBER: "X-Session-Sequence-Number",
|
||||
TRANSACTION_ID: "X-Transaction-Id",
|
||||
EON: "X-EON",
|
||||
EON: "X-Enterprise-Order-Number",
|
||||
};
|
||||
|
|
|
|||
|
|
@ -93,7 +93,6 @@ import textBlock from "@/digital-components/text-block/text-block";
|
|||
|
||||
//Supporting files
|
||||
import baseMixin from "@/mixins/base-mixin.js";
|
||||
import analyticsMixin from "@/mixins/analytics-mixin";
|
||||
import store from "@/store";
|
||||
import { storeActions } from "@/constants/store-actions";
|
||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||
|
|
@ -107,7 +106,8 @@ import { get12HourTimeFormat, get12HourTimeMobileFormat } from "@/helpers/date-h
|
|||
import { coverageStatus } from "@/constants/insurance";
|
||||
import { getDisplayTextForDurationLength } from "@/helpers/duration-length-helper";
|
||||
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 {
|
||||
name: "confirmation",
|
||||
|
|
@ -169,8 +169,17 @@ export default {
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
isRecalibrationOnOrder() {
|
||||
return containsLineItemWithPartType(
|
||||
partTypeStrings.RECALIBRATION,
|
||||
this?.lineItems?.supportingItems
|
||||
);
|
||||
},
|
||||
shouldHideRecalibration() {
|
||||
return this.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE);
|
||||
return (
|
||||
this.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE)?.toLowerCase() ===
|
||||
"true" && this.isRecalibrationOnOrder
|
||||
);
|
||||
},
|
||||
ShowCart() {
|
||||
if (this.isPia && this.submittedOrder?.settledTenderAmount == 0) {
|
||||
|
|
|
|||
|
|
@ -593,8 +593,8 @@ export default {
|
|||
},
|
||||
shouldHideRecalibration() {
|
||||
return (
|
||||
this.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE).toLowerCase() === "true" &&
|
||||
this.isRecalibrationOnOrder
|
||||
this.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE)?.toLowerCase() ===
|
||||
"true" && this.isRecalibrationOnOrder
|
||||
);
|
||||
},
|
||||
showApplePay() {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import store from "@/store";
|
|||
import * as navigateToHeritage from "@/helpers/heritage-integration/navigation-helper";
|
||||
import { nextTick } from "vue";
|
||||
import { experimentSettings } from "@/constants/experiments";
|
||||
import experimentMixin from "@/mixins/experiment-mixin.js";
|
||||
import baseMixin from "@/mixins/base-mixin.js";
|
||||
import { containsLineItemWithPartType } from "../../helpers/service-package-helper";
|
||||
|
||||
|
|
@ -746,6 +747,14 @@ function setupMocks({ customMountOptions }) {
|
|||
...customMountOptions,
|
||||
});
|
||||
|
||||
mountOptions.mixins = [
|
||||
{
|
||||
methods: {
|
||||
getSettingValue: jest.fn(),
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
baseMixin.methods.ResetExternalParamsAndHideModal = jest.fn();
|
||||
baseMixin.methods.isFormValid = jest.fn().mockReturnValue(true);
|
||||
mountOptions.global.mocks["$store"] = store;
|
||||
|
|
|
|||
|
|
@ -113,8 +113,7 @@ import { storeActions } from "@/constants/store-actions";
|
|||
import { deepClone } from "@/helpers/object-helper";
|
||||
import store from "@/store";
|
||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||
import { experimentUniverses, experimentSettings } from "@/constants/experiments";
|
||||
import { getSessionKeyValue, getUserIdValue } from "@/helpers/heritage-integration/cookie-helper";
|
||||
import { experimentSettings } from "@/constants/experiments";
|
||||
import { required } from "@/helpers/validation-rules";
|
||||
import { errorMessages } from "@/constants/error-messages";
|
||||
import { Form, defineRule } from "vee-validate";
|
||||
|
|
@ -129,7 +128,10 @@ import { queryStrings } from "@/constants/query-strings";
|
|||
import { getQuerystringParameter } from "@/helpers/querystring-helper";
|
||||
import promoModalQuestion from "@/fmg-components/promo-modal-question/promo-modal-question";
|
||||
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 { packageNames } from "@/constants/package-names";
|
||||
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
||||
|
|
@ -296,8 +298,12 @@ export default {
|
|||
const serviceLocationState = store.getters.order.serviceLocation.state;
|
||||
// Override if coming back from QuoteDetails. Remove override after Quote release
|
||||
const isInsuranceOverrideValue = to.query?.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
|
||||
if (
|
||||
serviceLocationState != null &&
|
||||
|
|
@ -309,15 +315,17 @@ export default {
|
|||
} else if (defaultIsInsuranceSelectedValue != null) {
|
||||
return defaultIsInsuranceSelectedValue;
|
||||
} else {
|
||||
// TEMPORARY CODE WHILE DEVELOPING
|
||||
if (availableLineItems) {
|
||||
let tierOnePackagePriceTemp = baseMixin.methods.getTierOnePackagePrice(
|
||||
baseMixin.methods.filterOutFees(availableLineItems)
|
||||
);
|
||||
let whatToReturn = baseMixin.methods.getTierOnePackagePrice(
|
||||
baseMixin.methods.filterOutFees(availableLineItems)
|
||||
) > insuranceThreshold;
|
||||
return whatToReturn; // TODO AJC: TIGHTEN THIS BACK UP AFTER TESTING
|
||||
const lineItemsForCalculatingPrice = hideRecalCost
|
||||
? baseMixin.methods.filterOutFees(
|
||||
baseMixin.methods.filterOutRecalibration(availableLineItems) // Strip out recal before filtering out fees
|
||||
)
|
||||
: baseMixin.methods.filterOutFees(availableLineItems);
|
||||
|
||||
return (
|
||||
baseMixin.methods.getTierOnePackagePrice(lineItemsForCalculatingPrice) >
|
||||
insuranceThreshold
|
||||
); // compare base price vs arbitrary threshold (representing insurance price)
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -328,15 +336,20 @@ export default {
|
|||
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;
|
||||
vm.isInsuranceSelected = getIsInsuranceSelectedValue(vm.availableLineItems, thresholdToUse);
|
||||
vm.isInsuranceSelected = getIsInsuranceSelectedValue(
|
||||
vm.availableLineItems,
|
||||
thresholdToUse
|
||||
);
|
||||
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.servicePackage = store.getters.externalParameterQuote.servicePackage;
|
||||
await nextTick();
|
||||
|
|
@ -348,7 +361,9 @@ export default {
|
|||
}
|
||||
} else {
|
||||
// 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
|
||||
if (externalSource?.includes("LeadGen")) {
|
||||
|
|
@ -359,10 +374,12 @@ export default {
|
|||
} else {
|
||||
if (internalThreshold) thresholdToUse = internalThreshold;
|
||||
}
|
||||
vm.isInsuranceSelected = getIsInsuranceSelectedValue(vm.availableLineItems, thresholdToUse);
|
||||
vm.isInsuranceSelected = getIsInsuranceSelectedValue(
|
||||
vm.availableLineItems,
|
||||
thresholdToUse
|
||||
);
|
||||
baseMixin.methods.ResetExternalParamsAndHideModal();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
@ -387,11 +404,23 @@ export default {
|
|||
this?.availableLineItems
|
||||
);
|
||||
},
|
||||
shouldHideRecalibration() {
|
||||
const recalSettingValue = experimentMixin.methods.getSettingValue(
|
||||
experimentSettings.RECAL_PRICE_REMOVE
|
||||
isServicePackageDiscountOnOrder() {
|
||||
return containsLineItemWithPartType(
|
||||
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() {
|
||||
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() {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
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";
|
||||
|
|
@ -237,7 +236,7 @@ export default {
|
|||
return (this.isInsuranceSelected ? "As little as $" : "$") + formattedPriceFloat;
|
||||
},
|
||||
getPackagePrice(packageName, { discountedPrice = false, servicePackageDiscount = false }) {
|
||||
var lineItemsToPrice = [...this.nullSafeAvailableLineItems];
|
||||
let lineItemsToPrice = [...this.nullSafeAvailableLineItems];
|
||||
|
||||
if (this.isRecalibrationOnOrder && this.shouldHideRecalibration) {
|
||||
lineItemsToPrice = lineItemsToPrice.filter((item) => {
|
||||
|
|
|
|||
|
|
@ -433,6 +433,18 @@ export default {
|
|||
if (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) {
|
||||
if (this.zipContainsMilitaryBase !== val) {
|
||||
|
|
@ -607,7 +619,7 @@ export default {
|
|||
},
|
||||
false
|
||||
);
|
||||
console.log(this.billToAccountNumber);
|
||||
|
||||
if (this.billToAccountNumber) {
|
||||
this.dispatchStoreAction(
|
||||
this.storeActions.SAVE_BILL_TO_ACCOUNT_NUMBER,
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ import { nextTick } from "vue";
|
|||
import { getAvailabilityRating } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper";
|
||||
|
||||
import { Provider } from "@/layouts/service-location/classes/provider";
|
||||
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
|
||||
|
||||
defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
|
||||
|
||||
|
|
@ -125,6 +126,8 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
async getNextShopsFromList(numberToGet = 3) {
|
||||
const logFirstShopsDisplayed = this.shopIndex == 0;
|
||||
|
||||
const shopIterator = (array, n) => {
|
||||
const l = array.length;
|
||||
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) {
|
||||
this.answers = mappedData;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -211,6 +211,13 @@ export default {
|
|||
payload.glassToReplace = glassString;
|
||||
}
|
||||
|
||||
//EON
|
||||
if (order.eon) {
|
||||
payload.eon = order.eon;
|
||||
} else {
|
||||
payload.eon = "";
|
||||
}
|
||||
|
||||
// Work Order Id
|
||||
if (order.workOrderId) {
|
||||
const parsedId = parseInt(order.workOrderId);
|
||||
|
|
|
|||
|
|
@ -1537,12 +1537,9 @@ export const actions = {
|
|||
? context.getters.payment.billToAccountNumber
|
||||
: applicationConfig.CASH_DEFAULT_BILL_TO_ACCOUNT_NUMBER;
|
||||
|
||||
const covStatus = context.getters.payment?.insuranceCoverage?.coverageStatus;
|
||||
const covSubStatus = context.getters.payment?.insuranceCoverage?.coverageSubStatus;
|
||||
|
||||
return globalMethods.callHttpClient({
|
||||
method: endpoints.GetMobileFeePart.method,
|
||||
endpoint: `${endpoints.GetMobileFeePart.url}/${damageType}/${parentAccountNumber}/${billToAccountNumber}/${covStatus}/${covSubStatus}`,
|
||||
endpoint: `${endpoints.GetMobileFeePart.url}/${damageType}/${parentAccountNumber}/${billToAccountNumber}`,
|
||||
logApiCall: true,
|
||||
pageNameToLog: pageNameToLog,
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue