Merge branch 'develop' into feature/csr-2147
This commit is contained in:
commit
a0cec6e83e
30 changed files with 932 additions and 105 deletions
|
|
@ -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 = {
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,10 @@ const endpoints = {
|
||||||
url: "/account/api/v1/account/insurance-companies",
|
url: "/account/api/v1/account/insurance-companies",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
},
|
},
|
||||||
|
GetBillToAccountNumber: {
|
||||||
|
url: "/account/api/v1/account/bill-to-account-number",
|
||||||
|
method: "GET",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export { endpoints };
|
export { endpoints };
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ const experimentSettings = {
|
||||||
IS_EMAIL_OPTIONAL: "isEmailOptional",
|
IS_EMAIL_OPTIONAL: "isEmailOptional",
|
||||||
SERVICE_PACKAGE_DISCOUNT: "OfferServicePackageDiscount",
|
SERVICE_PACKAGE_DISCOUNT: "OfferServicePackageDiscount",
|
||||||
RECAL_PRICE_REMOVE: "RecalPriceRemove",
|
RECAL_PRICE_REMOVE: "RecalPriceRemove",
|
||||||
|
INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL: "NextGen_InternalInsuranceTabDisplayThreshold",
|
||||||
|
INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL: "NextGen_ExternalInsuranceTabDisplayThreshold",
|
||||||
};
|
};
|
||||||
|
|
||||||
const experimentTriggers = {
|
const experimentTriggers = {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
export const headerKeys = {
|
export const headerKeys = {
|
||||||
EXPERIMENT: "X-Experiment-Data",
|
EXPERIMENT: "X-Experiment-Data",
|
||||||
|
APPLICATION_NAME: "X-Application-Name",
|
||||||
|
REFERRAL_SEQUENCE_NUMBER: "X-Referral-Sequence-Number",
|
||||||
|
SESSION_SEQUENCE_NUMBER: "X-Session-Sequence-Number",
|
||||||
|
TRANSACTION_ID: "X-Transaction-Id",
|
||||||
|
EON: "X-Enterprise-Order-Number",
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ const queryStrings = {
|
||||||
CJUNCTION: "cjunction",
|
CJUNCTION: "cjunction",
|
||||||
ORGANIC: "organic",
|
ORGANIC: "organic",
|
||||||
ORGANIC_SOCIAL: "organic_social",
|
ORGANIC_SOCIAL: "organic_social",
|
||||||
|
EXPERIMENTS: "experiments",
|
||||||
};
|
};
|
||||||
|
|
||||||
export { queryStrings };
|
export { queryStrings };
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ const storeActions = {
|
||||||
VALIDATE_ORDER_PROMO_AND_SAVE_SERVER_DATA: "validateOrderPromoAndSaveServerData",
|
VALIDATE_ORDER_PROMO_AND_SAVE_SERVER_DATA: "validateOrderPromoAndSaveServerData",
|
||||||
REVALIDATE_ORDER_PROMOS_AND_SAVE_SERVER_DATA: "revalidateOrderPromosAndSaveServerData",
|
REVALIDATE_ORDER_PROMOS_AND_SAVE_SERVER_DATA: "revalidateOrderPromosAndSaveServerData",
|
||||||
GET_INSURANCE_COMPANY_LIST: "getInsuranceCompanyList",
|
GET_INSURANCE_COMPANY_LIST: "getInsuranceCompanyList",
|
||||||
|
GET_BILL_TO_ACCOUNT_NUMBER: "getBillToAccountNumber",
|
||||||
GET_RECAL_PARTS_AND_SAVE_TO_LINE_ITEMS: "getRecalPartsAndSaveToLineItems",
|
GET_RECAL_PARTS_AND_SAVE_TO_LINE_ITEMS: "getRecalPartsAndSaveToLineItems",
|
||||||
|
|
||||||
// DEPENDENCY MUTATIONS
|
// DEPENDENCY MUTATIONS
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ const storeMutations = {
|
||||||
UPDATE_EXTERNAL_PARAMETER_IS_INSURANCE: "updateExternalParameterIsInsurance",
|
UPDATE_EXTERNAL_PARAMETER_IS_INSURANCE: "updateExternalParameterIsInsurance",
|
||||||
UPDATE_EXTERNAL_PARAMETER_VIN_SELECTION: "updateExternalParameterVinSelection",
|
UPDATE_EXTERNAL_PARAMETER_VIN_SELECTION: "updateExternalParameterVinSelection",
|
||||||
UPDATE_EXTERNAL_PARAMETER_SERVICE_PACKAGE: "updateExternalParameterServicePackage",
|
UPDATE_EXTERNAL_PARAMETER_SERVICE_PACKAGE: "updateExternalParameterServicePackage",
|
||||||
|
UPDATE_EXTERNAL_PARAMETER_SOURCE: "updateExternalParameterSource",
|
||||||
|
|
||||||
//RESET EXTERNAL_PARAMETER MUTATIONS
|
//RESET EXTERNAL_PARAMETER MUTATIONS
|
||||||
RESET_EXTERNAL_PARAMETER_VEHICLE_STATE: "resetExternalParameterVehicleState",
|
RESET_EXTERNAL_PARAMETER_VEHICLE_STATE: "resetExternalParameterVehicleState",
|
||||||
|
|
@ -110,6 +111,7 @@ const storeMutations = {
|
||||||
RESET_EXTERNAL_PARAMETER_ESTIMATE_STATE: "resetExternalParameterEstimateState",
|
RESET_EXTERNAL_PARAMETER_ESTIMATE_STATE: "resetExternalParameterEstimateState",
|
||||||
RESET_EXTERNAL_PARAMETER_SERVICEZIP_STATE: "resetExternalParameterServiceZipState",
|
RESET_EXTERNAL_PARAMETER_SERVICEZIP_STATE: "resetExternalParameterServiceZipState",
|
||||||
RESET_EXTERNAL_PARAMETER_QUOTE_STATE: "resetExternalParameterQuoteState",
|
RESET_EXTERNAL_PARAMETER_QUOTE_STATE: "resetExternalParameterQuoteState",
|
||||||
|
RESET_EXTERNAL_PARAMETER_SOURCE_STATE: "resetExternalParameterSourceState",
|
||||||
RESET_IS_EXTERNAL_PARAMETER: "resetIsExternalParameter",
|
RESET_IS_EXTERNAL_PARAMETER: "resetIsExternalParameter",
|
||||||
|
|
||||||
//Affiliate Cookies
|
//Affiliate Cookies
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ export default {
|
||||||
return this.leftAlignHeader ? "justify-content-start" : "justify-content-center";
|
return this.leftAlignHeader ? "justify-content-start" : "justify-content-center";
|
||||||
},
|
},
|
||||||
subText() {
|
subText() {
|
||||||
return this.getCmsContent(this.cmsWidgetName, "HeaderSubText");
|
return this.getCmsContent(this.cmsWidgetName, "SubheaderText");
|
||||||
},
|
},
|
||||||
backButtonAccessibleText() {
|
backButtonAccessibleText() {
|
||||||
return this.getCmsContent(this.cmsWidgetName, "BackButtonAccessibleText");
|
return this.getCmsContent(this.cmsWidgetName, "BackButtonAccessibleText");
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import analyticsMixIn from "@/mixins/analytics-mixin.js";
|
import analyticsMixIn from "@/mixins/analytics-mixin.js";
|
||||||
|
import baseMixin from "@/mixins/base-mixin.js";
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
|
|
||||||
|
|
@ -57,9 +58,17 @@ export default {
|
||||||
}) {
|
}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO;
|
const cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO;
|
||||||
|
const submittedOrder = baseMixin.methods.getSubmittedOrder();
|
||||||
|
const hasSubmittedOrder = baseMixin.methods.hasSubmittedOrder();
|
||||||
|
const order = hasSubmittedOrder ? submittedOrder : store.getters.order;
|
||||||
const payloadAndAnalyticsData = Object.assign({}, payload, { AppName: "FixMyGlass" });
|
const payloadAndAnalyticsData = Object.assign({}, payload, { AppName: "FixMyGlass" });
|
||||||
const headers = {
|
const headers = {
|
||||||
[headerKeys.EXPERIMENT]: JSON.stringify(store.getters.experimentSettings),
|
[headerKeys.EXPERIMENT]: JSON.stringify(store.getters.experimentSettings),
|
||||||
|
[headerKeys.APPLICATION_NAME]: applicationConfig.APPLICATION_NAME,
|
||||||
|
[headerKeys.SESSION_SEQUENCE_NUMBER]: store.getters.applicationUser?.savedSessionId,
|
||||||
|
[headerKeys.REFERRAL_SEQUENCE_NUMBER]: order?.referralSequenceNumber,
|
||||||
|
[headerKeys.TRANSACTION_ID]: crypto.randomUUID(),
|
||||||
|
[headerKeys.EON]: order?.eon,
|
||||||
};
|
};
|
||||||
|
|
||||||
axios({
|
axios({
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ global.$logger = {
|
||||||
logError: jest.fn(),
|
logError: jest.fn(),
|
||||||
logCritical: jest.fn(),
|
logCritical: jest.fn(),
|
||||||
};
|
};
|
||||||
|
global.crypto = { randomUUID: jest.fn() };
|
||||||
|
|
||||||
it("Global Methods - Call Http Client - Should Resolve Promise", () => {
|
it("Global Methods - Call Http Client - Should Resolve Promise", () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ export async function saveSession({
|
||||||
pageNameToLog,
|
pageNameToLog,
|
||||||
shouldAwaitSaveSessionQueue = false,
|
shouldAwaitSaveSessionQueue = false,
|
||||||
submitAfterSave = false,
|
submitAfterSave = false,
|
||||||
createDeleteStatusWorkOrderForPia = false,
|
createUnscheduledStatusWorkOrderForPIA = false,
|
||||||
}) {
|
}) {
|
||||||
var saveSessionPromise;
|
var saveSessionPromise;
|
||||||
if (store.getters.applicationUser.saveSessionPromise) {
|
if (store.getters.applicationUser.saveSessionPromise) {
|
||||||
|
|
@ -67,7 +67,7 @@ export async function saveSession({
|
||||||
return saveSessionHelper(
|
return saveSessionHelper(
|
||||||
pageNameToLog,
|
pageNameToLog,
|
||||||
submitAfterSave,
|
submitAfterSave,
|
||||||
createDeleteStatusWorkOrderForPia
|
createUnscheduledStatusWorkOrderForPIA
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -75,7 +75,7 @@ export async function saveSession({
|
||||||
saveSessionPromise = saveSessionHelper(
|
saveSessionPromise = saveSessionHelper(
|
||||||
pageNameToLog,
|
pageNameToLog,
|
||||||
submitAfterSave,
|
submitAfterSave,
|
||||||
createDeleteStatusWorkOrderForPia
|
createUnscheduledStatusWorkOrderForPIA
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
store.commit(storeMutations.UPDATE_SAVE_SESSION_PROMISE, saveSessionPromise);
|
store.commit(storeMutations.UPDATE_SAVE_SESSION_PROMISE, saveSessionPromise);
|
||||||
|
|
@ -88,13 +88,13 @@ export async function saveSession({
|
||||||
export async function submitWorkOrder({
|
export async function submitWorkOrder({
|
||||||
pageNameToLog,
|
pageNameToLog,
|
||||||
submitAfterSave = false,
|
submitAfterSave = false,
|
||||||
createDeleteStatusWorkOrderForPia = false,
|
createUnscheduledStatusWorkOrderForPIA = false,
|
||||||
}) {
|
}) {
|
||||||
await saveSession({
|
await saveSession({
|
||||||
pageNameToLog: pageNameToLog,
|
pageNameToLog: pageNameToLog,
|
||||||
shouldAwaitSaveSessionQueue: true,
|
shouldAwaitSaveSessionQueue: true,
|
||||||
submitAfterSave: submitAfterSave,
|
submitAfterSave: submitAfterSave,
|
||||||
createDeleteStatusWorkOrderForPia: createDeleteStatusWorkOrderForPia,
|
createUnscheduledStatusWorkOrderForPIA: createUnscheduledStatusWorkOrderForPIA,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -139,13 +139,13 @@ async function loadSession(
|
||||||
async function saveSessionHelper(
|
async function saveSessionHelper(
|
||||||
pageNameToLog,
|
pageNameToLog,
|
||||||
submitAfterSave = false,
|
submitAfterSave = false,
|
||||||
createDeleteStatusWorkOrderForPia = false
|
createUnscheduledStatusWorkOrderForPIA = false
|
||||||
) {
|
) {
|
||||||
const savedSessionInfo = await baseMixin.methods.dispatchStoreActionWithLogging(
|
const savedSessionInfo = await baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
storeActions.SAVE_SESSION,
|
storeActions.SAVE_SESSION,
|
||||||
{
|
{
|
||||||
submitAfterSave: submitAfterSave,
|
submitAfterSave: submitAfterSave,
|
||||||
createDeleteStatusWorkOrderForPia: createDeleteStatusWorkOrderForPia,
|
createUnscheduledStatusWorkOrderForPIA: createUnscheduledStatusWorkOrderForPIA,
|
||||||
},
|
},
|
||||||
pageNameToLog
|
pageNameToLog
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ describe("saveSession", () => {
|
||||||
// Assert
|
// Assert
|
||||||
expect(mocks.baseMixin.methods.dispatchStoreActionWithLogging).toHaveBeenCalledWith(
|
expect(mocks.baseMixin.methods.dispatchStoreActionWithLogging).toHaveBeenCalledWith(
|
||||||
storeActions.SAVE_SESSION,
|
storeActions.SAVE_SESSION,
|
||||||
{ createDeleteStatusWorkOrderForPia: false, submitAfterSave: false },
|
{ createUnscheduledStatusWorkOrderForPIA: false, submitAfterSave: false },
|
||||||
"test"
|
"test"
|
||||||
);
|
);
|
||||||
expect(mocks.baseMixin.methods.dispatchStoreAction).toHaveBeenCalledWith(
|
expect(mocks.baseMixin.methods.dispatchStoreAction).toHaveBeenCalledWith(
|
||||||
|
|
@ -287,7 +287,7 @@ describe("submitWorkOrder", () => {
|
||||||
// Assert
|
// Assert
|
||||||
expect(mocks.baseMixin.methods.dispatchStoreActionWithLogging).toHaveBeenCalledWith(
|
expect(mocks.baseMixin.methods.dispatchStoreActionWithLogging).toHaveBeenCalledWith(
|
||||||
storeActions.SAVE_SESSION,
|
storeActions.SAVE_SESSION,
|
||||||
{ createDeleteStatusWorkOrderForPia: false, submitAfterSave: true },
|
{ createUnscheduledStatusWorkOrderForPIA: false, submitAfterSave: true },
|
||||||
"test"
|
"test"
|
||||||
);
|
);
|
||||||
expect(mocks.baseMixin.methods.dispatchStoreAction).toHaveBeenCalledWith(
|
expect(mocks.baseMixin.methods.dispatchStoreAction).toHaveBeenCalledWith(
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ jest.mock("@/helpers/cms-content-helper", () => ({
|
||||||
fetchCmsContentForPage: jest.fn(),
|
fetchCmsContentForPage: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
global.crypto = { randomUUID: jest.fn() };
|
||||||
describe("estimate.vue", () => {
|
describe("estimate.vue", () => {
|
||||||
test("Selected vin option is emitted upon selection.", async () => {
|
test("Selected vin option is emitted upon selection.", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
|
|
|
||||||
|
|
@ -552,23 +552,21 @@ export default {
|
||||||
},
|
},
|
||||||
async setupPia() {
|
async setupPia() {
|
||||||
this.$refs.loadingModal.showModal();
|
this.$refs.loadingModal.showModal();
|
||||||
|
|
||||||
// if we don't have a work order in delete substatus, set the flag and submit.
|
|
||||||
// we need a work order number for pia so we can pass it to safeliteHop.
|
// we need a work order number for pia so we can pass it to safeliteHop.
|
||||||
if (!store.getters.order.workOrderNumber) {
|
// this will create one in delete substatus.
|
||||||
try {
|
try {
|
||||||
await submitWorkOrder({
|
await submitWorkOrder({
|
||||||
pageNameToLog: "payment-method",
|
pageNameToLog: "payment-method",
|
||||||
submitAfterSave: false,
|
submitAfterSave: false,
|
||||||
createDeleteStatusWorkOrderForPia: true,
|
createUnscheduledStatusWorkOrderForPIA: true,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("error: response from pia submit work order:" + error.message);
|
console.log("error: response from pia submit work order:" + error.message);
|
||||||
this.dispatchStoreAction(storeActions.RESET_SAVE_SESSION_PROMISE);
|
this.dispatchStoreAction(storeActions.RESET_SAVE_SESSION_PROMISE);
|
||||||
this.$route.query[queryStrings.DISPLAY_PIA_ALERT] = true;
|
this.$route.query[queryStrings.DISPLAY_PIA_ALERT] = true;
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dispatchStoreAction(storeActions.RESET_SAVE_SESSION_PROMISE);
|
this.dispatchStoreAction(storeActions.RESET_SAVE_SESSION_PROMISE);
|
||||||
this.$router.navigateWithoutSaving(
|
this.$router.navigateWithoutSaving(
|
||||||
this.navigationScenarios.CLICKED_PAY_NOW,
|
this.navigationScenarios.CLICKED_PAY_NOW,
|
||||||
|
|
@ -596,7 +594,10 @@ export default {
|
||||||
return containsRecalParts(order.lineItems);
|
return containsRecalParts(order.lineItems);
|
||||||
},
|
},
|
||||||
shouldHideRecalibration() {
|
shouldHideRecalibration() {
|
||||||
return this.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE);
|
return (
|
||||||
|
this.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE)?.toLowerCase() ===
|
||||||
|
"true" && this.isRecalibrationOnOrder
|
||||||
|
);
|
||||||
},
|
},
|
||||||
showApplePay() {
|
showApplePay() {
|
||||||
return baseMixin.methods.showApplePay();
|
return baseMixin.methods.showApplePay();
|
||||||
|
|
|
||||||
|
|
@ -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";
|
||||||
|
|
||||||
|
|
@ -169,12 +170,12 @@ describe("quote.vue", () => {
|
||||||
damage: {
|
damage: {
|
||||||
isRepair: true,
|
isRepair: true,
|
||||||
},
|
},
|
||||||
referralNumber: "1234567",
|
payment: {
|
||||||
},
|
insuranceCoverage: {
|
||||||
payment: {
|
isVerified: false,
|
||||||
insuranceCoverage: {
|
},
|
||||||
isVerified: false,
|
|
||||||
},
|
},
|
||||||
|
referralNumber: "1234567",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
|
|
@ -198,10 +199,10 @@ describe("quote.vue", () => {
|
||||||
lineItems: {
|
lineItems: {
|
||||||
glassParts: ["item", "item2"],
|
glassParts: ["item", "item2"],
|
||||||
},
|
},
|
||||||
},
|
payment: {
|
||||||
payment: {
|
insuranceCoverage: {
|
||||||
insuranceCoverage: {
|
isVerified: false,
|
||||||
isVerified: false,
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -391,12 +392,11 @@ describe("quote.vue", () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
wrapper.vm.$route = { query: { isInsurance: "false" } };
|
|
||||||
|
|
||||||
//Act
|
//Act
|
||||||
await quote.beforeRouteEnter.call(
|
await quote.beforeRouteEnter.call(
|
||||||
wrapper.vm,
|
wrapper.vm,
|
||||||
{ query: { fmgPage: "quote" } },
|
{ query: { fmgPage: "quote", isInsurance: false } },
|
||||||
undefined,
|
undefined,
|
||||||
(c) => c(wrapper.vm)
|
(c) => c(wrapper.vm)
|
||||||
);
|
);
|
||||||
|
|
@ -747,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;
|
||||||
|
|
|
||||||
|
|
@ -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,13 +128,18 @@ 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";
|
||||||
import { containsRecalParts } from "@/helpers/recal-helper";
|
import { containsRecalParts } from "@/helpers/recal-helper";
|
||||||
defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
|
defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
|
||||||
|
|
||||||
|
const INSURANCE_TAB_TO_DISPLAY_THRESHOLD_DEFAULT = 300;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "quote",
|
name: "quote",
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
|
|
@ -208,7 +212,10 @@ export default {
|
||||||
...servicePackageDiscountPart,
|
...servicePackageDiscountPart,
|
||||||
];
|
];
|
||||||
|
|
||||||
// When calling pricing from the quote page, always use the cash parent account
|
// 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
|
||||||
|
var holdParentAccountNumber = store.getters.order.payment?.parentAccountNumber;
|
||||||
|
var holdBillToAccountNumber = store.getters.order.payment?.billToAccountNumber;
|
||||||
|
|
||||||
baseMixin.methods.dispatchStoreAction(
|
baseMixin.methods.dispatchStoreAction(
|
||||||
storeActions.SAVE_PARENT_ACCOUNT_NUMBER,
|
storeActions.SAVE_PARENT_ACCOUNT_NUMBER,
|
||||||
applicationConfig.CASH_PARENT_ACCOUNT_NUMBER,
|
applicationConfig.CASH_PARENT_ACCOUNT_NUMBER,
|
||||||
|
|
@ -260,7 +267,8 @@ export default {
|
||||||
vm.addableVaps = addableVaps;
|
vm.addableVaps = addableVaps;
|
||||||
vm.lineItems = lineItems;
|
vm.lineItems = lineItems;
|
||||||
vm.availableLineItems = pricingResults;
|
vm.availableLineItems = pricingResults;
|
||||||
vm.isInsuranceSelected = vm.getDefaultIsInsuranceSelectedValue(vm.availableLineItems);
|
vm.holdParentAccountNumber = holdParentAccountNumber;
|
||||||
|
vm.holdBillToAccountNumber = holdBillToAccountNumber;
|
||||||
|
|
||||||
if (revalidatePromoResponse) {
|
if (revalidatePromoResponse) {
|
||||||
const revalidateAlerts = buildToastMessagesFromRevalidateOrValidatePromoResponse(
|
const revalidateAlerts = buildToastMessagesFromRevalidateOrValidatePromoResponse(
|
||||||
|
|
@ -281,21 +289,68 @@ export default {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a safeguard to prevent verified insurance from seeing quote page again.
|
||||||
const payment = store.getters.payment;
|
const payment = store.getters.payment;
|
||||||
const policy = store.getters.policy;
|
if (payment?.isInsurance && payment?.insuranceCoverage?.isVerified) {
|
||||||
if (payment?.isInsurance) {
|
navigateToHeritageFunnel({ shouldSaveSession: true, pageNameToLog: "quote" });
|
||||||
const vehicleChangedDuringPolicyLookupInHeritage =
|
|
||||||
payment.insuranceCoverage?.coverageStatus && policy?.policyNumber !== "";
|
|
||||||
|
|
||||||
// This is a safeguard to prevent insurance from seeing quote page again.
|
|
||||||
// Usually this is caught in vehicle-questions-mixin with a referral length 6 check
|
|
||||||
if (vehicleChangedDuringPolicyLookupInHeritage) {
|
|
||||||
navigateToHeritageFunnel({ shouldSaveSession: true, pageNameToLog: "quote" });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (store.getters.externalParameterState?.isExternalParameter) {
|
const getIsInsuranceSelectedValue = (availableLineItems, insuranceThreshold) => {
|
||||||
|
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 &&
|
||||||
|
payWithInsuranceStates.find((item) => item === serviceLocationState)
|
||||||
|
)
|
||||||
|
return true;
|
||||||
|
else if (isInsuranceOverrideValue != null) {
|
||||||
|
return isInsuranceOverrideValue == "true";
|
||||||
|
} else if (defaultIsInsuranceSelectedValue != null) {
|
||||||
|
return defaultIsInsuranceSelectedValue;
|
||||||
|
} else {
|
||||||
|
if (availableLineItems) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let thresholdToUse = INSURANCE_TAB_TO_DISPLAY_THRESHOLD_DEFAULT;
|
||||||
|
let internalThreshold = experimentMixin.methods.getSettingValue(
|
||||||
|
experimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!store.getters.externalParameterState?.isExternalParameter) {
|
||||||
|
// there are no external parameters
|
||||||
|
|
||||||
|
if (internalThreshold) thresholdToUse = internalThreshold;
|
||||||
|
vm.isInsuranceSelected = getIsInsuranceSelectedValue(
|
||||||
|
vm.availableLineItems,
|
||||||
|
thresholdToUse
|
||||||
|
);
|
||||||
|
baseMixin.methods.ResetExternalParamsAndHideModal();
|
||||||
|
} else {
|
||||||
|
// there ARE external parameters
|
||||||
|
|
||||||
if (store.getters.externalParameterQuote.isInsurance == true) {
|
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();
|
||||||
|
|
@ -306,10 +361,26 @@ export default {
|
||||||
baseMixin.methods.ResetExternalParamsAndHideModal();
|
baseMixin.methods.ResetExternalParamsAndHideModal();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// did user come from external source (LeadGen)?
|
||||||
|
let externalSource = store.getters.externalParameterSource
|
||||||
|
? store.getters.externalParameterSource
|
||||||
|
: null;
|
||||||
|
|
||||||
|
// Business logic to determine what "external" source is
|
||||||
|
if (externalSource?.includes("LeadGen")) {
|
||||||
|
const externalThreshold = experimentMixin.methods.getSettingValue(
|
||||||
|
experimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL
|
||||||
|
);
|
||||||
|
if (externalThreshold) thresholdToUse = externalThreshold;
|
||||||
|
} else {
|
||||||
|
if (internalThreshold) thresholdToUse = internalThreshold;
|
||||||
|
}
|
||||||
|
vm.isInsuranceSelected = getIsInsuranceSelectedValue(
|
||||||
|
vm.availableLineItems,
|
||||||
|
thresholdToUse
|
||||||
|
);
|
||||||
baseMixin.methods.ResetExternalParamsAndHideModal();
|
baseMixin.methods.ResetExternalParamsAndHideModal();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
baseMixin.methods.ResetExternalParamsAndHideModal();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -320,6 +391,8 @@ export default {
|
||||||
lineItems: [],
|
lineItems: [],
|
||||||
addableVaps: [],
|
addableVaps: [],
|
||||||
servicePackage: null,
|
servicePackage: null,
|
||||||
|
holdParentAccountNumber: null,
|
||||||
|
holdBillToAccountNumber: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -329,11 +402,23 @@ export default {
|
||||||
isRecalibrationOnOrder() {
|
isRecalibrationOnOrder() {
|
||||||
return containsRecalParts(this.lineItems);
|
return containsRecalParts(this.lineItems);
|
||||||
},
|
},
|
||||||
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 (
|
||||||
|
|
@ -350,39 +435,46 @@ export default {
|
||||||
this.$refs[modalName].openModal();
|
this.$refs[modalName].openModal();
|
||||||
},
|
},
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
|
const payment = store.getters.order.payment;
|
||||||
|
const log = getQuerystringParameter(queryStrings.LOG);
|
||||||
|
if (eval(log)) {
|
||||||
|
console.log("quote.vue pagePrereqs:");
|
||||||
|
console.log(
|
||||||
|
new Date() +
|
||||||
|
" store.getters.order.serviceLocation.zipCode: " +
|
||||||
|
store.getters.order.serviceLocation?.zipCode
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
new Date() +
|
||||||
|
" store.getters.order.serviceLocation.zipCodeCtu: " +
|
||||||
|
store.getters.order.serviceLocation?.zipCodeCtu
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
new Date() +
|
||||||
|
" store.getters.order.damage.isRepair: " +
|
||||||
|
store.getters.order.damage?.isRepair
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
new Date() +
|
||||||
|
" store.getters.order.lineItems?.glassParts: " +
|
||||||
|
JSON.stringify(store.getters.order.lineItems?.glassParts)
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
new Date() +
|
||||||
|
" store.getters.order.payment.insuranceCoverage?.isVerified: " +
|
||||||
|
payment?.insuranceCoverage?.isVerified
|
||||||
|
);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
store.getters.order.serviceLocation.zipCode &&
|
store.getters.order.serviceLocation.zipCode &&
|
||||||
store.getters.order.serviceLocation.zipCodeCtu &&
|
store.getters.order.serviceLocation.zipCodeCtu &&
|
||||||
(store.getters.order.damage.isRepair ||
|
(store.getters.order.damage.isRepair ||
|
||||||
(store.getters.order.lineItems?.glassParts != null &&
|
(store.getters.order.lineItems?.glassParts != null &&
|
||||||
store.getters.order.lineItems.glassParts.length > 0)) &&
|
store.getters.order.lineItems.glassParts.length > 0)) &&
|
||||||
store.getters.order.referralNumber?.length !== 6
|
(payment.insuranceCoverage?.isVerified == null ||
|
||||||
|
payment.insuranceCoverage?.isVerified === false)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
getDefaultIsInsuranceSelectedValue(availableLineItems) {
|
|
||||||
const serviceLocationState = store.getters.order.serviceLocation.state;
|
|
||||||
// Override if coming back from QuoteDetails. Remove override after Quote release
|
|
||||||
const isInsuranceOverrideValue = this.$route.query?.isInsurance;
|
|
||||||
|
|
||||||
const defaultIsInsuranceSelectedValue = this.$store.getters.order.payment.isInsurance;
|
|
||||||
//Default to Insurance Tab if user Service zip is from certain States
|
|
||||||
if (
|
|
||||||
serviceLocationState != null &&
|
|
||||||
payWithInsuranceStates.find((item) => item === serviceLocationState)
|
|
||||||
)
|
|
||||||
return true;
|
|
||||||
else if (isInsuranceOverrideValue != null) {
|
|
||||||
return isInsuranceOverrideValue == "true";
|
|
||||||
} else if (defaultIsInsuranceSelectedValue != null) {
|
|
||||||
return defaultIsInsuranceSelectedValue;
|
|
||||||
} else {
|
|
||||||
return availableLineItems
|
|
||||||
? baseMixin.methods.getTierOnePackagePrice(
|
|
||||||
baseMixin.methods.filterOutFees(availableLineItems)
|
|
||||||
) > 300
|
|
||||||
: null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
vapsItemsSelectedAction(vapsItemsSelected) {
|
vapsItemsSelectedAction(vapsItemsSelected) {
|
||||||
this.lineItems.vaps = vapsItemsSelected;
|
this.lineItems.vaps = vapsItemsSelected;
|
||||||
},
|
},
|
||||||
|
|
@ -410,6 +502,17 @@ export default {
|
||||||
applicationConfig.CASH_DEFAULT_BILL_TO_ACCOUNT_NUMBER,
|
applicationConfig.CASH_DEFAULT_BILL_TO_ACCOUNT_NUMBER,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
baseMixin.methods.dispatchStoreAction(
|
||||||
|
storeActions.SAVE_PARENT_ACCOUNT_NUMBER,
|
||||||
|
this.holdParentAccountNumber,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
baseMixin.methods.dispatchStoreAction(
|
||||||
|
storeActions.SAVE_BILL_TO_ACCOUNT_NUMBER,
|
||||||
|
this.holdBillToAccountNumber,
|
||||||
|
false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
@ -473,6 +576,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() {
|
||||||
|
|
|
||||||
|
|
@ -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";
|
||||||
|
|
@ -238,7 +237,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 = getItemsWithoutRecalParts(lineItemsToPrice);
|
lineItemsToPrice = getItemsWithoutRecalParts(lineItemsToPrice);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import baseMixin from "@/mixins/base-mixin.js";
|
||||||
|
|
||||||
export async function getPricedMobileFeePart(serviceZipCode, pageNameToLog) {
|
export async function getPricedMobileFeePart(serviceZipCode, pageNameToLog) {
|
||||||
if (!serviceZipCode) {
|
if (!serviceZipCode) {
|
||||||
return Promise.resolve(null);
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const zipCodeData = await baseMixin.methods.getZipCodeData(serviceZipCode, pageNameToLog);
|
const zipCodeData = await baseMixin.methods.getZipCodeData(serviceZipCode, pageNameToLog);
|
||||||
|
|
@ -36,12 +36,12 @@ export async function getPricedMobileFeePart(serviceZipCode, pageNameToLog) {
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
return Promise.resolve(pricingResults[0]);
|
return pricingResults[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getServiceabilityDetails(serviceZipCode, lineItems, pageNameToLog) {
|
export async function getServiceabilityDetails(serviceZipCode, lineItems, pageNameToLog) {
|
||||||
// Get the Mobile Fee Part
|
// Get the Mobile Fee Part
|
||||||
const serviceabilityDetails = await baseMixin.methods.dispatchStoreActionWithLogging(
|
return await baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
storeActions.GET_SERVICEABILITY_DETAILS,
|
storeActions.GET_SERVICEABILITY_DETAILS,
|
||||||
{
|
{
|
||||||
serviceZipCode: serviceZipCode,
|
serviceZipCode: serviceZipCode,
|
||||||
|
|
@ -50,20 +50,26 @@ export async function getServiceabilityDetails(serviceZipCode, lineItems, pageNa
|
||||||
pageNameToLog,
|
pageNameToLog,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return Promise.resolve(serviceabilityDetails);
|
export async function getBillToAccountNumber(providerNumber) {
|
||||||
|
// Get the BillTo Account Number
|
||||||
|
return await baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
|
storeActions.GET_BILL_TO_ACCOUNT_NUMBER,
|
||||||
|
{ providerNumber: providerNumber },
|
||||||
|
"service-location",
|
||||||
|
false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getShopProviderData(serviceZipCode) {
|
export async function getShopProviderData(serviceZipCode) {
|
||||||
const shopProviderData = await baseMixin.methods.dispatchStoreActionWithLogging(
|
return await baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
storeActions.GET_PROVIDERS,
|
storeActions.GET_PROVIDERS,
|
||||||
{
|
{
|
||||||
serviceZipCode: serviceZipCode,
|
serviceZipCode: serviceZipCode,
|
||||||
},
|
},
|
||||||
"service-location"
|
"service-location"
|
||||||
);
|
);
|
||||||
|
|
||||||
return Promise.resolve(shopProviderData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAvailabilityRating(
|
export async function getAvailabilityRating(
|
||||||
|
|
@ -92,5 +98,5 @@ export async function getAvailabilityRating(
|
||||||
|
|
||||||
const shopStatus = isGoodAvailability ? "high" : "low";
|
const shopStatus = isGoodAvailability ? "high" : "low";
|
||||||
|
|
||||||
return Promise.resolve(shopStatus);
|
return shopStatus;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import mobileLocationModalQuestions from "./mobile-location-modal-questions";
|
||||||
import { mount, shallowMount } from "@vue/test-utils";
|
import { mount, shallowMount } from "@vue/test-utils";
|
||||||
import { storeActions } from "@/constants/store-actions";
|
import { storeActions } from "@/constants/store-actions";
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
import { getBillToAccountNumber } from "../helpers/service-location-helper/service-location-helper";
|
||||||
|
|
||||||
const linkWidgetName = "linkWidgetName";
|
const linkWidgetName = "linkWidgetName";
|
||||||
const modalWidgetName = "modalWidgetName";
|
const modalWidgetName = "modalWidgetName";
|
||||||
|
|
@ -125,6 +126,9 @@ jest.mock(
|
||||||
getServiceabilityDetails: jest.fn((mockServiceZipCode) => {
|
getServiceabilityDetails: jest.fn((mockServiceZipCode) => {
|
||||||
return mockGetServiceabilityDetails(mockServiceZipCode);
|
return mockGetServiceabilityDetails(mockServiceZipCode);
|
||||||
}),
|
}),
|
||||||
|
getBillToAccountNumber: jest.fn(() => {
|
||||||
|
return "87291";
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@ import { deepClone } from "@/helpers/object-helper";
|
||||||
import {
|
import {
|
||||||
getPricedMobileFeePart,
|
getPricedMobileFeePart,
|
||||||
getServiceabilityDetails,
|
getServiceabilityDetails,
|
||||||
|
getBillToAccountNumber,
|
||||||
} from "@/layouts/service-location/helpers/service-location-helper/service-location-helper";
|
} from "@/layouts/service-location/helpers/service-location-helper/service-location-helper";
|
||||||
|
|
||||||
// Validation
|
// Validation
|
||||||
|
|
@ -91,7 +92,12 @@ import { v4 as uuidv4 } from "uuid";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "mobile-location-modal-questions",
|
name: "mobile-location-modal-questions",
|
||||||
emits: ["update:modelValue", "updated-mobile-fee-part", "updated-contains-military-base"],
|
emits: [
|
||||||
|
"update:modelValue",
|
||||||
|
"updated-mobile-fee-part",
|
||||||
|
"updated-contains-military-base",
|
||||||
|
"updated-bill-to-account-number",
|
||||||
|
],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
internalModel: deepClone(this.modelValue),
|
internalModel: deepClone(this.modelValue),
|
||||||
|
|
@ -266,11 +272,16 @@ export default {
|
||||||
"service-location"
|
"service-location"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const billToAccountNumber = await getBillToAccountNumber(
|
||||||
|
this.internalModel.zipCodeCtu
|
||||||
|
);
|
||||||
|
|
||||||
// update content related to service zip code
|
// update content related to service zip code
|
||||||
this.$emit("updated-mobile-fee-part", mobileFeePart);
|
this.$emit("updated-mobile-fee-part", mobileFeePart);
|
||||||
this.$emit("updated-serviceability", serviceabilityDetails.data);
|
this.$emit("updated-serviceability", serviceabilityDetails.data);
|
||||||
this.$emit("updated-contains-military-base", zipCodeData.containsMilitaryBase);
|
this.$emit("updated-contains-military-base", zipCodeData.containsMilitaryBase);
|
||||||
this.$emit("updated-mobile-ctu", zipCodeData.zipCodeCtu);
|
this.$emit("updated-mobile-ctu", zipCodeData.zipCodeCtu);
|
||||||
|
this.$emit("updated-bill-to-account-number", billToAccountNumber);
|
||||||
|
|
||||||
// update the page level model
|
// update the page level model
|
||||||
this.$emit("update:modelValue", this.internalModel);
|
this.$emit("update:modelValue", this.internalModel);
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
@updated-mobile-fee-part="setMobileFeePart"
|
@updated-mobile-fee-part="setMobileFeePart"
|
||||||
@updated-serviceability="setServiceabilityDetails"
|
@updated-serviceability="setServiceabilityDetails"
|
||||||
@updated-contains-military-base="setContainsMilitaryBase"
|
@updated-contains-military-base="setContainsMilitaryBase"
|
||||||
|
@updated-bill-to-account-number="setBillToAccountNumber"
|
||||||
linkWidgetName="ServiceZipLinkWidget"
|
linkWidgetName="ServiceZipLinkWidget"
|
||||||
modalWidgetName="ServiceZipModalWidget" />
|
modalWidgetName="ServiceZipModalWidget" />
|
||||||
|
|
||||||
|
|
@ -191,6 +192,7 @@ export default {
|
||||||
mobileFeePart: null,
|
mobileFeePart: null,
|
||||||
zipContainsMilitaryBase: false,
|
zipContainsMilitaryBase: false,
|
||||||
zipCodeCtu: null,
|
zipCodeCtu: null,
|
||||||
|
billToAccountNumber: null,
|
||||||
shopProviderData: null,
|
shopProviderData: null,
|
||||||
navigatingForward: false,
|
navigatingForward: false,
|
||||||
};
|
};
|
||||||
|
|
@ -431,12 +433,27 @@ 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) {
|
||||||
this.zipContainsMilitaryBase = val;
|
this.zipContainsMilitaryBase = val;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
setBillToAccountNumber(val) {
|
||||||
|
this.billToAccountNumber = val;
|
||||||
|
},
|
||||||
setCtuForMobile(val) {
|
setCtuForMobile(val) {
|
||||||
this.zipCodeCtu = val;
|
this.zipCodeCtu = val;
|
||||||
},
|
},
|
||||||
|
|
@ -498,7 +515,8 @@ export default {
|
||||||
this.recalibrationInformationModal.openModal();
|
this.recalibrationInformationModal.openModal();
|
||||||
},
|
},
|
||||||
backButtonAction() {
|
backButtonAction() {
|
||||||
if (store.getters.order.payment.isInsurance) {
|
const payment = store.getters.order.payment;
|
||||||
|
if (payment?.isInsurance && payment?.insuranceCoverage?.isVerified) {
|
||||||
navigateToHeritageFunnel({ shouldSaveSession: false });
|
navigateToHeritageFunnel({ shouldSaveSession: false });
|
||||||
} else {
|
} else {
|
||||||
this.$router.navigateWithoutSaving(
|
this.$router.navigateWithoutSaving(
|
||||||
|
|
@ -602,6 +620,14 @@ export default {
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (this.billToAccountNumber) {
|
||||||
|
this.dispatchStoreAction(
|
||||||
|
this.storeActions.SAVE_BILL_TO_ACCOUNT_NUMBER,
|
||||||
|
this.billToAccountNumber,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.updateAndSaveSupportingItems();
|
this.updateAndSaveSupportingItems();
|
||||||
this.$router.navigateWithSaving(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
this.$router.navigateWithSaving(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { mount, shallowMount } from "@vue/test-utils";
|
import { mount, shallowMount } from "@vue/test-utils";
|
||||||
import serviceZipModalQuestion from "./service-zip-modal-question";
|
import serviceZipModalQuestion from "./service-zip-modal-question";
|
||||||
|
import { getBillToAccountNumber } from "../helpers/service-location-helper/service-location-helper";
|
||||||
|
|
||||||
jest.mock("@/digital-components/textbox-question/textbox-question", () => ({
|
jest.mock("@/digital-components/textbox-question/textbox-question", () => ({
|
||||||
getCmsContent: jest.fn((widgetName, cmsFieldName) => {
|
getCmsContent: jest.fn((widgetName, cmsFieldName) => {
|
||||||
|
|
@ -51,6 +52,9 @@ jest.mock(
|
||||||
getServiceabilityDetails: jest.fn((mockServiceZipCode) => {
|
getServiceabilityDetails: jest.fn((mockServiceZipCode) => {
|
||||||
return mockGetServiceabilityDetails(mockServiceZipCode);
|
return mockGetServiceabilityDetails(mockServiceZipCode);
|
||||||
}),
|
}),
|
||||||
|
getBillToAccountNumber: jest.fn((mockServiceZipCodeCtu) => {
|
||||||
|
return "87291";
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,17 @@ import alert from "@/ux-components/alert/alert";
|
||||||
import {
|
import {
|
||||||
getPricedMobileFeePart,
|
getPricedMobileFeePart,
|
||||||
getServiceabilityDetails,
|
getServiceabilityDetails,
|
||||||
|
getBillToAccountNumber,
|
||||||
} from "@/layouts/service-location/helpers/service-location-helper/service-location-helper";
|
} from "@/layouts/service-location/helpers/service-location-helper/service-location-helper";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "service-zip-modal-question",
|
name: "service-zip-modal-question",
|
||||||
emits: ["update:modelValue", "updated-mobile-fee-part", "updated-contains-military-base"],
|
emits: [
|
||||||
|
"update:modelValue",
|
||||||
|
"updated-mobile-fee-part",
|
||||||
|
"updated-contains-military-base",
|
||||||
|
"updated-bill-to-account-number",
|
||||||
|
],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
internalModel: this.copyModel(this.modelValue),
|
internalModel: this.copyModel(this.modelValue),
|
||||||
|
|
@ -165,10 +171,15 @@ export default {
|
||||||
"service-location"
|
"service-location"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const billToAccountNumber = await getBillToAccountNumber(
|
||||||
|
this.internalModel.zipCodeCtu
|
||||||
|
);
|
||||||
|
|
||||||
// update content related to service zip code
|
// update content related to service zip code
|
||||||
this.$emit("updated-mobile-fee-part", mobileFeePart);
|
this.$emit("updated-mobile-fee-part", mobileFeePart);
|
||||||
this.$emit("updated-serviceability", serviceabilityDetails.data);
|
this.$emit("updated-serviceability", serviceabilityDetails.data);
|
||||||
this.$emit("updated-contains-military-base", zipCodeData.containsMilitaryBase);
|
this.$emit("updated-contains-military-base", zipCodeData.containsMilitaryBase);
|
||||||
|
this.$emit("updated-bill-to-account-number", billToAccountNumber);
|
||||||
|
|
||||||
// update the page level model
|
// update the page level model
|
||||||
this.$emit("update:modelValue", this.internalModel);
|
this.$emit("update:modelValue", this.internalModel);
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,7 @@ export default {
|
||||||
const supportingItemsPromise = await this.dispatchStoreActionWithLogging(
|
const supportingItemsPromise = await this.dispatchStoreActionWithLogging(
|
||||||
storeActions.GET_SUPPORTING_ITEMS,
|
storeActions.GET_SUPPORTING_ITEMS,
|
||||||
null,
|
null,
|
||||||
"estimate"
|
"service-zip"
|
||||||
);
|
);
|
||||||
|
|
||||||
const promiseResultMap = [
|
const promiseResultMap = [
|
||||||
|
|
@ -232,7 +232,7 @@ export default {
|
||||||
);
|
);
|
||||||
|
|
||||||
// call saveSession here - navigateWithSaving saves too late in the flow
|
// call saveSession here - navigateWithSaving saves too late in the flow
|
||||||
await saveSession({ pageNameToLog: "estimate" });
|
await saveSession({ pageNameToLog: "service-zip" });
|
||||||
return this.$router.navigateWithSaving(
|
return this.$router.navigateWithSaving(
|
||||||
this.navigationScenarios.CLICKED_FORWARD_WITH_NO_QUESTIONS,
|
this.navigationScenarios.CLICKED_FORWARD_WITH_NO_QUESTIONS,
|
||||||
this.$route
|
this.$route
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
@ -384,6 +391,257 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
pushProductArrayToDataLayer() {
|
||||||
|
// Get correct order object
|
||||||
|
const hasSubmittedOrder = baseMixin.methods.hasSubmittedOrder();
|
||||||
|
const submittedOrder = baseMixin.methods.getSubmittedOrder();
|
||||||
|
|
||||||
|
if (hasSubmittedOrder) {
|
||||||
|
var lineItems = submittedOrder.lineItems ? submittedOrder.lineItems : {};
|
||||||
|
|
||||||
|
// combine all line items
|
||||||
|
var combinedLineItems = [
|
||||||
|
...(lineItems.glassParts ?? []),
|
||||||
|
...(lineItems.supportingItems ?? []),
|
||||||
|
...(lineItems.vaps ?? []),
|
||||||
|
...(lineItems.promos ?? []),
|
||||||
|
];
|
||||||
|
|
||||||
|
//Get child parts
|
||||||
|
combinedLineItems = flattenArray(combinedLineItems);
|
||||||
|
|
||||||
|
var products = [];
|
||||||
|
var discount = 0;
|
||||||
|
var coupon = "";
|
||||||
|
var subTotal = 0;
|
||||||
|
for (var i = 0; i < combinedLineItems.length; i++) {
|
||||||
|
let part = combinedLineItems[i];
|
||||||
|
let productSku = part.partNumber;
|
||||||
|
let productType = part.partType;
|
||||||
|
let promoCode = part.promoCode;
|
||||||
|
let productPrice = baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts(
|
||||||
|
[part],
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
if (productSku == "DISCOUNT" || productType == "SERVICE PACKAGE DISCOUNT") {
|
||||||
|
if (coupon) {
|
||||||
|
coupon += ",";
|
||||||
|
}
|
||||||
|
if (productSku == "DISCOUNT") {
|
||||||
|
coupon += promoCode;
|
||||||
|
} else {
|
||||||
|
coupon += productSku;
|
||||||
|
}
|
||||||
|
|
||||||
|
discount += productPrice * -1;
|
||||||
|
} else {
|
||||||
|
products.push({
|
||||||
|
productType: productType,
|
||||||
|
productSku: productSku,
|
||||||
|
productPrice: productPrice.toFixed(2),
|
||||||
|
productQuantity: "1",
|
||||||
|
});
|
||||||
|
subTotal += productPrice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pushToDataLayerIfDefined({
|
||||||
|
productArray: {
|
||||||
|
coupon: coupon,
|
||||||
|
discount: discount.toFixed(2),
|
||||||
|
subTotal: subTotal.toFixed(2),
|
||||||
|
products: products,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
pushECommerceCartToDataLayer() {
|
||||||
|
const isDefined = (x) => x !== null && x !== undefined;
|
||||||
|
// Get correct order object
|
||||||
|
const hasSubmittedOrder = baseMixin.methods.hasSubmittedOrder();
|
||||||
|
const submittedOrder = baseMixin.methods.getSubmittedOrder();
|
||||||
|
if (hasSubmittedOrder) {
|
||||||
|
var lineItems = submittedOrder.lineItems ? submittedOrder.lineItems : {};
|
||||||
|
var supportingItems =
|
||||||
|
submittedOrder.lineItems && submittedOrder.lineItems.supportingItems
|
||||||
|
? submittedOrder.lineItems.supportingItems
|
||||||
|
: [];
|
||||||
|
var insurance = submittedOrder.payment && submittedOrder.payment.isInsurance;
|
||||||
|
var itac = submittedOrder.policy && submittedOrder.policy.isItac;
|
||||||
|
var nocomp = submittedOrder.policy && submittedOrder.policy.isNoComp;
|
||||||
|
|
||||||
|
var recalLineItem = supportingItems.filter(function (lineItem) {
|
||||||
|
return lineItem.partType.indexOf("RECALIBRATION") !== -1;
|
||||||
|
});
|
||||||
|
var disposalFee = supportingItems.filter(function (lineItem) {
|
||||||
|
return lineItem.partType.indexOf("DISPOSAL FEE") !== -1;
|
||||||
|
});
|
||||||
|
var mobileFee = supportingItems.filter(function (lineItem) {
|
||||||
|
return lineItem.partType.indexOf("MOBILE FEE") !== -1;
|
||||||
|
});
|
||||||
|
var repairFee = supportingItems.filter(function (lineItem) {
|
||||||
|
return lineItem.partType.indexOf("REPAIR FEE") !== -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
var vaps =
|
||||||
|
submittedOrder.lineItems && submittedOrder.lineItems.vaps
|
||||||
|
? submittedOrder.lineItems.vaps
|
||||||
|
: [];
|
||||||
|
var wipers = vaps.filter(function (lineItem) {
|
||||||
|
return (
|
||||||
|
lineItem.partType.indexOf("FRONT WIPER") !== -1 ||
|
||||||
|
lineItem.partType.indexOf("REAR WIPER") !== -1
|
||||||
|
);
|
||||||
|
});
|
||||||
|
var rainDefense = vaps.filter(function (lineItem) {
|
||||||
|
return lineItem.partType.indexOf("RAIN DEFENSE") !== -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Combine line items
|
||||||
|
var combinedLineItems = [];
|
||||||
|
if (lineItems.glassParts) {
|
||||||
|
combinedLineItems = combinedLineItems.concat(lineItems.glassParts);
|
||||||
|
}
|
||||||
|
if (recalLineItem) {
|
||||||
|
combinedLineItems = combinedLineItems.concat(recalLineItem);
|
||||||
|
}
|
||||||
|
if (disposalFee) {
|
||||||
|
combinedLineItems = combinedLineItems.concat(disposalFee);
|
||||||
|
}
|
||||||
|
if (mobileFee && !(insurance && !itac && !nocomp)) {
|
||||||
|
combinedLineItems = combinedLineItems.concat(mobileFee);
|
||||||
|
}
|
||||||
|
if (repairFee) {
|
||||||
|
combinedLineItems = combinedLineItems.concat(repairFee);
|
||||||
|
}
|
||||||
|
if (wipers) {
|
||||||
|
combinedLineItems = combinedLineItems.concat(wipers);
|
||||||
|
}
|
||||||
|
if (rainDefense) {
|
||||||
|
combinedLineItems = combinedLineItems.concat(rainDefense);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remove child Parts if any
|
||||||
|
combinedLineItems.forEach((lineItem) => {
|
||||||
|
lineItem.childParts = [];
|
||||||
|
});
|
||||||
|
|
||||||
|
var isPricingAvailable =
|
||||||
|
combinedLineItems.length > 0 &&
|
||||||
|
combinedLineItems.every(function (lineItem) {
|
||||||
|
return (
|
||||||
|
isDefined(lineItem.kitPrice) &&
|
||||||
|
isDefined(lineItem.laborAmount) &&
|
||||||
|
isDefined(lineItem.sellingPrice)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
let subtotal = 0;
|
||||||
|
if (isPricingAvailable) {
|
||||||
|
subtotal = baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts(
|
||||||
|
combinedLineItems,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
pushToDataLayerIfDefined({
|
||||||
|
eCommerceCart: { products: combinedLineItems, subTotal: parseInt(subtotal) },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
pushCommissionJunctionGtmDataToDataLayer() {
|
||||||
|
// helper check for if an object is defined (but maybe falsey)
|
||||||
|
const isDefined = (x) => x !== null && x !== undefined;
|
||||||
|
let repairReplace = "";
|
||||||
|
let coupons = "";
|
||||||
|
let refSequenceNum = "";
|
||||||
|
let accountType = "";
|
||||||
|
let amount = 0;
|
||||||
|
let cjEvent = "";
|
||||||
|
if (store.getters.applicationUser.affiliateCookies?.length > 0) {
|
||||||
|
const affiliateCookies = store.getters.applicationUser.affiliateCookies;
|
||||||
|
var cookieArray = [];
|
||||||
|
affiliateCookies.forEach((item) => {
|
||||||
|
let cookieObject = convertCookieStringToObject(item.CookieValue);
|
||||||
|
cookieArray.push(cookieObject);
|
||||||
|
});
|
||||||
|
const sortedCookies = cookieArray.sort(
|
||||||
|
(a, b) =>
|
||||||
|
new Date(b.timestamp.replace("/", "T")) -
|
||||||
|
new Date(a.timestamp.replace("/", "T"))
|
||||||
|
);
|
||||||
|
const filteredCookie = sortedCookies?.find(
|
||||||
|
(x) => x.tagEvent?.length > 0 && x.batchEvent?.length > 0
|
||||||
|
);
|
||||||
|
if (isDefined(filteredCookie)) {
|
||||||
|
cjEvent = filteredCookie.tagEvent;
|
||||||
|
const hasSubmittedOrder = baseMixin.methods.hasSubmittedOrder();
|
||||||
|
const submittedOrder = baseMixin.methods.getSubmittedOrder();
|
||||||
|
|
||||||
|
if (hasSubmittedOrder) {
|
||||||
|
repairReplace = submittedOrder.damage.isRepair ? "Repair" : "Replace";
|
||||||
|
const promos = submittedOrder.lineItems.promos ?? [];
|
||||||
|
if (promos.length === 0) {
|
||||||
|
coupons = "";
|
||||||
|
} else {
|
||||||
|
const promoCodes = promos.map((promo) => promo.promoCode);
|
||||||
|
const promoString = promoCodes.reduce(
|
||||||
|
(prev, next) => `${prev}_${next}`
|
||||||
|
);
|
||||||
|
coupons = promoString;
|
||||||
|
}
|
||||||
|
const serviceZipPackage = submittedOrder.lineItems?.supportingItems?.find(
|
||||||
|
(x) => x.partType == "SERVICE PACKAGE DISCOUNT"
|
||||||
|
);
|
||||||
|
if (isDefined(serviceZipPackage)) {
|
||||||
|
if (coupons) {
|
||||||
|
coupons += ",";
|
||||||
|
}
|
||||||
|
coupons += serviceZipPackage.partNumber;
|
||||||
|
}
|
||||||
|
refSequenceNum = submittedOrder.referralSequenceNumber;
|
||||||
|
|
||||||
|
if (isDefined(submittedOrder.payment.isInsurance)) {
|
||||||
|
accountType = submittedOrder.payment.isInsurance ? "insurance" : "cash";
|
||||||
|
} else {
|
||||||
|
accountType = "";
|
||||||
|
}
|
||||||
|
const lineItems = submittedOrder.lineItems ?? {};
|
||||||
|
const combinedLineItems = [
|
||||||
|
...(lineItems.glassParts ?? []),
|
||||||
|
...(lineItems.supportingItems ?? []),
|
||||||
|
...(lineItems.vaps ?? []),
|
||||||
|
...(lineItems.promos ?? []),
|
||||||
|
];
|
||||||
|
|
||||||
|
const isPricingAvailable =
|
||||||
|
combinedLineItems.length > 0 &&
|
||||||
|
combinedLineItems.every(
|
||||||
|
(lineItem) =>
|
||||||
|
isDefined(lineItem.kitPrice) &&
|
||||||
|
isDefined(lineItem.laborAmount) &&
|
||||||
|
isDefined(lineItem.sellingPrice)
|
||||||
|
);
|
||||||
|
if (accountType == "cash" && isPricingAvailable) {
|
||||||
|
amount = baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts(
|
||||||
|
combinedLineItems,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pushToDataLayerIfDefined({
|
||||||
|
commissionJunctionGtmData: {
|
||||||
|
cj_commission_junction_event: cjEvent,
|
||||||
|
cj_referral_sequence_number: refSequenceNum,
|
||||||
|
cj_amount: amount.toFixed(2),
|
||||||
|
cj_repair_replace: repairReplace,
|
||||||
|
cj_coupon: coupons,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
prependActionToMethod(object, method, actionToPrepend) {
|
prependActionToMethod(object, method, actionToPrepend) {
|
||||||
const baseMethodName = method.name.startsWith("bound ")
|
const baseMethodName = method.name.startsWith("bound ")
|
||||||
? method.name.substring(6)
|
? method.name.substring(6)
|
||||||
|
|
@ -496,3 +754,24 @@ function getValueToLog(value, valueToLogType) {
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function flattenArray(arr) {
|
||||||
|
let result = [];
|
||||||
|
arr.forEach((item) => {
|
||||||
|
result.push(item);
|
||||||
|
if (item.childParts) {
|
||||||
|
result = result.concat(item.childParts);
|
||||||
|
delete item.childParts; // Remove childParts after flattening
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertCookieStringToObject(cookieValue) {
|
||||||
|
const cookieObject = cookieValue.split("&").reduce((acc, pair) => {
|
||||||
|
const [key, value] = pair.split("=");
|
||||||
|
acc[key] = value;
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
return cookieObject;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -853,4 +853,198 @@ describe("analyticsMixin.js", () => {
|
||||||
expect(mocks.baseMixin.methods.dispatchStoreAction).toBeCalled();
|
expect(mocks.baseMixin.methods.dispatchStoreAction).toBeCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe("push product array and ecommerce cart to data layer", () => {
|
||||||
|
const mocks = setupMocksForJsFiles();
|
||||||
|
it("should push product array to data layer correctly", () => {
|
||||||
|
// Mock the methods
|
||||||
|
mocks.baseMixin.methods.hasSubmittedOrder = jest.fn();
|
||||||
|
mocks.baseMixin.methods.getSubmittedOrder = jest.fn();
|
||||||
|
mocks.baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts = jest.fn();
|
||||||
|
mocks.baseMixin.methods.hasSubmittedOrder.mockReturnValue(true);
|
||||||
|
mocks.baseMixin.methods.getSubmittedOrder.mockReturnValue({
|
||||||
|
lineItems: {
|
||||||
|
glassParts: [{ partNumber: "GP1", partType: "glass" }],
|
||||||
|
supportingItems: [{ partNumber: "SI1", partType: "support" }],
|
||||||
|
vaps: [{ partNumber: "VAP1", partType: "vap" }],
|
||||||
|
promos: [{ partNumber: "DISCOUNT", partType: "promo", promoCode: "PROMO4" }],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
mocks.baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts.mockReturnValue(100);
|
||||||
|
|
||||||
|
// Call the function
|
||||||
|
analyticsMixin.methods.pushProductArrayToDataLayer();
|
||||||
|
|
||||||
|
// Assertions
|
||||||
|
expect(mocks.baseMixin.methods.hasSubmittedOrder).toHaveBeenCalled();
|
||||||
|
expect(mocks.baseMixin.methods.getSubmittedOrder).toHaveBeenCalled();
|
||||||
|
expect(
|
||||||
|
mocks.baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts
|
||||||
|
).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
it("should push eCommerce cart to data layer correctly", () => {
|
||||||
|
// Mock the methods
|
||||||
|
mocks.baseMixin.methods.hasSubmittedOrder = jest.fn();
|
||||||
|
mocks.baseMixin.methods.getSubmittedOrder = jest.fn();
|
||||||
|
mocks.baseMixin.methods.hasSubmittedOrder.mockReturnValue(true);
|
||||||
|
mocks.baseMixin.methods.getSubmittedOrder.mockReturnValue({
|
||||||
|
lineItems: {
|
||||||
|
supportingItems: [
|
||||||
|
{ partType: "RECALIBRATION", partNumber: "R1" },
|
||||||
|
{ partType: "DISPOSAL FEE", partNumber: "D1" },
|
||||||
|
{ partType: "MOBILE FEE", partNumber: "M1" },
|
||||||
|
{ partType: "REPAIR FEE", partNumber: "RF1" },
|
||||||
|
],
|
||||||
|
vaps: [{ partType: "FRONT WIPER", partNumber: "FW1" }],
|
||||||
|
},
|
||||||
|
payment: { isInsurance: true },
|
||||||
|
policy: { isItac: true, isNoComp: false },
|
||||||
|
});
|
||||||
|
|
||||||
|
// Call the function
|
||||||
|
analyticsMixin.methods.pushECommerceCartToDataLayer();
|
||||||
|
|
||||||
|
// Assertions
|
||||||
|
expect(mocks.baseMixin.methods.hasSubmittedOrder).toHaveBeenCalled();
|
||||||
|
expect(mocks.baseMixin.methods.getSubmittedOrder).toHaveBeenCalled();
|
||||||
|
expect(
|
||||||
|
mocks.baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts
|
||||||
|
).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("pushCommissionJunctionGtmDataToDataLayer", () => {
|
||||||
|
const mocks = setupMocksForJsFiles();
|
||||||
|
it("should handle empty affiliateCookies", () => {
|
||||||
|
store.getters = {
|
||||||
|
applicationUser: {
|
||||||
|
affiliateCookies: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
mocks.baseMixin.methods.hasSubmittedOrder = jest.fn();
|
||||||
|
mocks.baseMixin.methods.hasSubmittedOrder.mockReturnValue(false);
|
||||||
|
const result = analyticsMixin.methods.pushCommissionJunctionGtmDataToDataLayer();
|
||||||
|
expect(result).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Pushes populated data to data layer", () => {
|
||||||
|
mocks.baseMixin.methods.hasSubmittedOrder = jest.fn();
|
||||||
|
mocks.baseMixin.methods.hasSubmittedOrder.mockReturnValue(true);
|
||||||
|
mocks.baseMixin.methods.getSubmittedOrder = jest.fn();
|
||||||
|
mocks.baseMixin.methods.getSubmittedOrder.mockReturnValue({
|
||||||
|
vehicle: {
|
||||||
|
year: "2020",
|
||||||
|
make: "acura",
|
||||||
|
model: "mdx",
|
||||||
|
style: "4-door sedan",
|
||||||
|
carId: "dummyCarId",
|
||||||
|
category: "dummyCategory",
|
||||||
|
vin: "dummyVin",
|
||||||
|
},
|
||||||
|
serviceLocation: {
|
||||||
|
address: "add1",
|
||||||
|
address2: "add2",
|
||||||
|
city: "city",
|
||||||
|
state: "state",
|
||||||
|
zipCode: "11111",
|
||||||
|
zipCodeCtu: "11110",
|
||||||
|
appointmentType: "IN_SHOP",
|
||||||
|
isVehicleProtected: true,
|
||||||
|
provider: {
|
||||||
|
providerNumber: 2,
|
||||||
|
address: {
|
||||||
|
streetAddress: "add3",
|
||||||
|
city: "city2",
|
||||||
|
state: "state2",
|
||||||
|
zipCode: "22222",
|
||||||
|
zipCodeCtu: "22220",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
techNotes: "",
|
||||||
|
},
|
||||||
|
customer: {
|
||||||
|
firstName: "first",
|
||||||
|
lastName: "last",
|
||||||
|
emailAddress: "builddigitaltest@safelite.com",
|
||||||
|
phoneNumber: "555-555-5555",
|
||||||
|
isSmsOptIn: false,
|
||||||
|
},
|
||||||
|
damage: {
|
||||||
|
isRepair: false,
|
||||||
|
numberOfChips: null,
|
||||||
|
glassToReplace: [{ glassName: "single", glassLocation: "windshield" }],
|
||||||
|
},
|
||||||
|
lineItems: {
|
||||||
|
glassParts: [parts.windshield],
|
||||||
|
supportingItems: [],
|
||||||
|
vaps: [parts.frontWipers],
|
||||||
|
promos: [
|
||||||
|
{
|
||||||
|
promoCode: "promoTEST",
|
||||||
|
kitPrice: 0,
|
||||||
|
sellingPrice: 0,
|
||||||
|
laborAmount: 0,
|
||||||
|
salesTax: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
promoCode: "promoTEST2",
|
||||||
|
kitPrice: 0,
|
||||||
|
sellingPrice: 0,
|
||||||
|
laborAmount: 0,
|
||||||
|
salesTax: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
payment: {
|
||||||
|
isInsurance: false,
|
||||||
|
insuranceCoverage: {
|
||||||
|
isVerified: null,
|
||||||
|
coverageStatus: null,
|
||||||
|
coverageVerificationType: null,
|
||||||
|
},
|
||||||
|
isPia: true,
|
||||||
|
piaType: "Afterpay",
|
||||||
|
inactivePromos: [],
|
||||||
|
},
|
||||||
|
schedule: {
|
||||||
|
date: "date",
|
||||||
|
startTime: "start",
|
||||||
|
endTime: "end",
|
||||||
|
jobMinMinutes: "30",
|
||||||
|
jobMaxMinutes: "45",
|
||||||
|
},
|
||||||
|
workOrderNumber: "01820-111111",
|
||||||
|
workOrderId: "222222222222",
|
||||||
|
referralSequenceNumber: "1111111",
|
||||||
|
});
|
||||||
|
store.getters = {
|
||||||
|
applicationUser: {
|
||||||
|
affiliateCookies: [
|
||||||
|
{
|
||||||
|
CookieName: "Cookie1",
|
||||||
|
CookieValue: "timestamp=2023-09-18/12:00:00&tagEvent=event1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CookieName: "Cookie2",
|
||||||
|
CookieValue: "timestamp=2023-09-19/12:00:00&tagEvent=event2",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
// Arrange
|
||||||
|
window.dataLayer = [];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
analyticsMixin.methods.pushCommissionJunctionGtmDataToDataLayer();
|
||||||
|
|
||||||
|
const result = window.dataLayer[0];
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
console.log(result);
|
||||||
|
const allFieldsPopulated = Object.keys(result).every(
|
||||||
|
(key) => result[key] === false || !!result[key]
|
||||||
|
);
|
||||||
|
expect(allFieldsPopulated).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,12 @@ const routes = [
|
||||||
|
|
||||||
await runExperiments(to.query.fmgPage);
|
await runExperiments(to.query.fmgPage);
|
||||||
|
|
||||||
|
//Affiliate Cookies
|
||||||
|
const affiliateCookies = getAffiliateCookies();
|
||||||
|
if (affiliateCookies != null && affiliateCookies.length > 0) {
|
||||||
|
store.commit(storeMutations.UPDATE_AFFILIATE_COOKIES, affiliateCookies);
|
||||||
|
}
|
||||||
|
setupAdvertiserTracking();
|
||||||
// Process funnel cookie.
|
// Process funnel cookie.
|
||||||
updateOrCreateFunnelCookie();
|
updateOrCreateFunnelCookie();
|
||||||
|
|
||||||
|
|
@ -307,6 +313,17 @@ router.afterEach(async (to, from) => {
|
||||||
|
|
||||||
// Push current order status to Data Layer
|
// Push current order status to Data Layer
|
||||||
analyticsMixin.methods.pushOrderToDataLayer();
|
analyticsMixin.methods.pushOrderToDataLayer();
|
||||||
|
|
||||||
|
if (to.query.fmgPage == fmgPageValues.CONFIRMATION) {
|
||||||
|
//Push Product Array to Data Layer
|
||||||
|
analyticsMixin.methods.pushProductArrayToDataLayer();
|
||||||
|
|
||||||
|
//Push Ecommerce Cart to Data Layer
|
||||||
|
analyticsMixin.methods.pushECommerceCartToDataLayer();
|
||||||
|
|
||||||
|
//Push Commission Junction Gtm Data To Data Layer
|
||||||
|
analyticsMixin.methods.pushCommissionJunctionGtmDataToDataLayer();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
router.navigateWithoutSaving = (
|
router.navigateWithoutSaving = (
|
||||||
|
|
@ -615,6 +632,7 @@ function updateExternalParameterState() {
|
||||||
const externalParameterVinSelection = getQuerystringParameter(queryStrings.VIN_SELECTION);
|
const externalParameterVinSelection = getQuerystringParameter(queryStrings.VIN_SELECTION);
|
||||||
const externalParameterServicePackage = getQuerystringParameter(queryStrings.SERVICE_PACKAGE);
|
const externalParameterServicePackage = getQuerystringParameter(queryStrings.SERVICE_PACKAGE);
|
||||||
const externalParameterNumberOfChips = getQuerystringParameter(queryStrings.NUMBER_OF_CHIPS);
|
const externalParameterNumberOfChips = getQuerystringParameter(queryStrings.NUMBER_OF_CHIPS);
|
||||||
|
const externalParameterSource = getQuerystringParameter(queryStrings.EXPERIMENTS);
|
||||||
if (
|
if (
|
||||||
externalParameterYear &&
|
externalParameterYear &&
|
||||||
externalParameterMake &&
|
externalParameterMake &&
|
||||||
|
|
@ -664,6 +682,9 @@ function updateExternalParameterState() {
|
||||||
externalParameterVinSelection
|
externalParameterVinSelection
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (externalParameterSource) {
|
||||||
|
store.commit(storeMutations.UPDATE_EXTERNAL_PARAMETER_SOURCE, externalParameterSource);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@ const getDefaultState = () => {
|
||||||
insuranceCoverage: {
|
insuranceCoverage: {
|
||||||
isVerified: null,
|
isVerified: null,
|
||||||
coverageStatus: null,
|
coverageStatus: null,
|
||||||
|
coverageSubStatus: null,
|
||||||
coverageType: null,
|
coverageType: null,
|
||||||
coverageVerificationType: null,
|
coverageVerificationType: null,
|
||||||
},
|
},
|
||||||
|
|
@ -473,6 +474,10 @@ export const mutations = {
|
||||||
externalParameterState.quote.servicePackage = servicePackage;
|
externalParameterState.quote.servicePackage = servicePackage;
|
||||||
saveExternalParameterState(externalParameterState);
|
saveExternalParameterState(externalParameterState);
|
||||||
},
|
},
|
||||||
|
updateExternalParameterSource(state, source) {
|
||||||
|
externalParameterState.source = source;
|
||||||
|
saveExternalParameterState(externalParameterState);
|
||||||
|
},
|
||||||
//RESET ExternalParameter MUTATIONS
|
//RESET ExternalParameter MUTATIONS
|
||||||
resetExternalParameterVehicleState(state) {
|
resetExternalParameterVehicleState(state) {
|
||||||
externalParameterState.vehicle.year = null;
|
externalParameterState.vehicle.year = null;
|
||||||
|
|
@ -503,6 +508,10 @@ export const mutations = {
|
||||||
externalParameterState.quote.servicePackage = null;
|
externalParameterState.quote.servicePackage = null;
|
||||||
saveExternalParameterState(externalParameterState);
|
saveExternalParameterState(externalParameterState);
|
||||||
},
|
},
|
||||||
|
resetExternalParameterSourceState(state) {
|
||||||
|
externalParameterState.source = null;
|
||||||
|
saveExternalParameterState(externalParameterState);
|
||||||
|
},
|
||||||
resetIsExternalParameter(state) {
|
resetIsExternalParameter(state) {
|
||||||
externalParameterState.isExternalParameter = null;
|
externalParameterState.isExternalParameter = null;
|
||||||
saveExternalParameterState(externalParameterState);
|
saveExternalParameterState(externalParameterState);
|
||||||
|
|
@ -683,6 +692,8 @@ export const mutations = {
|
||||||
state.order.payment.insuranceCoverage.coverageStatus = coverageStatusValue(
|
state.order.payment.insuranceCoverage.coverageStatus = coverageStatusValue(
|
||||||
sessionInformation?.order.insuranceCoverage.coverageStatus
|
sessionInformation?.order.insuranceCoverage.coverageStatus
|
||||||
);
|
);
|
||||||
|
state.order.payment.insuranceCoverage.coverageSubStatus =
|
||||||
|
sessionInformation?.order.insuranceCoverage.coverageSubStatus;
|
||||||
state.order.payment.insuranceCoverage.coverageType = coverageTypeValue(
|
state.order.payment.insuranceCoverage.coverageType = coverageTypeValue(
|
||||||
sessionInformation?.order.insuranceCoverage.coverageType
|
sessionInformation?.order.insuranceCoverage.coverageType
|
||||||
);
|
);
|
||||||
|
|
@ -905,6 +916,7 @@ export const getters = {
|
||||||
externalParameterQuote: (state) => externalParameterState?.quote,
|
externalParameterQuote: (state) => externalParameterState?.quote,
|
||||||
externalParameterServiceZip: (state) => externalParameterState?.serviceZip,
|
externalParameterServiceZip: (state) => externalParameterState?.serviceZip,
|
||||||
externalParameterEstimate: (state) => externalParameterState?.estimate,
|
externalParameterEstimate: (state) => externalParameterState?.estimate,
|
||||||
|
externalParameterSource: (state) => externalParameterState?.source,
|
||||||
};
|
};
|
||||||
|
|
||||||
function getNonFalseValuesOfPropertyInArrayOfObjects(array, propertyName) {
|
function getNonFalseValuesOfPropertyInArrayOfObjects(array, propertyName) {
|
||||||
|
|
@ -1810,8 +1822,8 @@ export const actions = {
|
||||||
const lineItems = context.state.order.lineItems;
|
const lineItems = context.state.order.lineItems;
|
||||||
|
|
||||||
const submitAfterSave = payload?.submitAfterSave === "true";
|
const submitAfterSave = payload?.submitAfterSave === "true";
|
||||||
const createDeleteStatusWorkOrderForPia =
|
const createUnscheduledStatusWorkOrderForPIA =
|
||||||
payload?.createDeleteStatusWorkOrderForPia === "true";
|
payload?.createUnscheduledStatusWorkOrderForPIA === "true";
|
||||||
|
|
||||||
// create a new array to avoid mutating state
|
// create a new array to avoid mutating state
|
||||||
const newGlassToReplace = convertGlassPieceNamingForApi(damage.glassToReplace);
|
const newGlassToReplace = convertGlassPieceNamingForApi(damage.glassToReplace);
|
||||||
|
|
@ -1882,6 +1894,7 @@ export const actions = {
|
||||||
},
|
},
|
||||||
isInsurance: order.payment.isInsurance,
|
isInsurance: order.payment.isInsurance,
|
||||||
parentAccountNumber: order.payment.parentAccountNumber,
|
parentAccountNumber: order.payment.parentAccountNumber,
|
||||||
|
billToAccountNumber: order.payment.billToAccountNumber,
|
||||||
inactivePromos: order.payment.inactivePromos,
|
inactivePromos: order.payment.inactivePromos,
|
||||||
isCreditCard:
|
isCreditCard:
|
||||||
order.payment.piaType == paymentMethods.CREDIT_CARD ? true : false,
|
order.payment.piaType == paymentMethods.CREDIT_CARD ? true : false,
|
||||||
|
|
@ -1945,7 +1958,7 @@ export const actions = {
|
||||||
referralNumber: order.referralNumber?.toString(),
|
referralNumber: order.referralNumber?.toString(),
|
||||||
referralSequenceNumber: order.referralSequenceNumber,
|
referralSequenceNumber: order.referralSequenceNumber,
|
||||||
eon: order.eon,
|
eon: order.eon,
|
||||||
createDeleteStatusWorkOrderForPia: createDeleteStatusWorkOrderForPia,
|
createUnscheduledStatusWorkOrderForPIA: createUnscheduledStatusWorkOrderForPIA,
|
||||||
lockToken: order.lockToken,
|
lockToken: order.lockToken,
|
||||||
isRecalAckOptIn: order.isRecalAckOptIn,
|
isRecalAckOptIn: order.isRecalAckOptIn,
|
||||||
},
|
},
|
||||||
|
|
@ -2671,6 +2684,10 @@ export const actions = {
|
||||||
|
|
||||||
return revalidateResponse?.data;
|
return revalidateResponse?.data;
|
||||||
},
|
},
|
||||||
|
///////////////////////////
|
||||||
|
// Account Service Calls //
|
||||||
|
///////////////////////////
|
||||||
|
|
||||||
// List all insurance companies
|
// List all insurance companies
|
||||||
async getInsuranceCompanyList(context, { pageNameToLog }) {
|
async getInsuranceCompanyList(context, { pageNameToLog }) {
|
||||||
const insuranceCompanyList = await globalMethods.callHttpClient({
|
const insuranceCompanyList = await globalMethods.callHttpClient({
|
||||||
|
|
@ -2693,6 +2710,40 @@ export const actions = {
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
// Get BillToAccountNumber
|
||||||
|
async getBillToAccountNumber(
|
||||||
|
context,
|
||||||
|
{
|
||||||
|
payload: {
|
||||||
|
parentAccountNumber = context.getters.order.payment.parentAccountNumber,
|
||||||
|
providerNumber = context.getters.order.serviceLocation.zipCodeCtu,
|
||||||
|
isItac = context.getters.order.policy.isItac,
|
||||||
|
},
|
||||||
|
pageNameToLog,
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
// Cash orders default to 87291 - update if/when more detailed
|
||||||
|
// billToAccountNumbers are needed for cash
|
||||||
|
if (parentAccountNumber == applicationConfig.CASH_PARENT_ACCOUNT_NUMBER) {
|
||||||
|
return applicationConfig.CASH_DEFAULT_BILL_TO_ACCOUNT_NUMBER;
|
||||||
|
}
|
||||||
|
const queryString =
|
||||||
|
`ParentAccountNumber=${parentAccountNumber}` +
|
||||||
|
`&ProviderNumber=${providerNumber}` +
|
||||||
|
`&IsItac=${isItac}`;
|
||||||
|
|
||||||
|
const billToAccountNumberResponse = await globalMethods.callHttpClient({
|
||||||
|
method: endpoints.GetBillToAccountNumber.method,
|
||||||
|
endpoint: `${endpoints.GetBillToAccountNumber.url}?${queryString}`,
|
||||||
|
logApiCall: true,
|
||||||
|
pageNameToLog: pageNameToLog,
|
||||||
|
});
|
||||||
|
|
||||||
|
return billToAccountNumberResponse.data.toString();
|
||||||
|
},
|
||||||
|
//////////////////////////////////
|
||||||
|
// END OF Account Service Calls //
|
||||||
|
//////////////////////////////////
|
||||||
|
|
||||||
// Misc order actions
|
// Misc order actions
|
||||||
saveSchedule(context, scheduleInfo) {
|
saveSchedule(context, scheduleInfo) {
|
||||||
|
|
@ -2835,6 +2886,7 @@ export const actions = {
|
||||||
context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_ESTIMATE_STATE);
|
context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_ESTIMATE_STATE);
|
||||||
context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_SERVICEZIP_STATE);
|
context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_SERVICEZIP_STATE);
|
||||||
context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_QUOTE_STATE);
|
context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_QUOTE_STATE);
|
||||||
|
context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_SOURCE_STATE);
|
||||||
context.commit(storeMutations.RESET_IS_EXTERNAL_PARAMETER);
|
context.commit(storeMutations.RESET_IS_EXTERNAL_PARAMETER);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -3378,6 +3430,7 @@ function createExternalParameterDefaultState() {
|
||||||
isInsurance: null,
|
isInsurance: null,
|
||||||
servicePackage: null,
|
servicePackage: null,
|
||||||
},
|
},
|
||||||
|
source: null,
|
||||||
};
|
};
|
||||||
// set to session storage
|
// set to session storage
|
||||||
saveExternalParameterState(externalParameterDefaultState);
|
saveExternalParameterState(externalParameterDefaultState);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue