Merge branch 'develop' into feature/CSR-1928
This commit is contained in:
commit
9ffaf61066
21 changed files with 415 additions and 82 deletions
|
|
@ -23,6 +23,7 @@ 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",
|
||||
|
|
|
|||
|
|
@ -84,6 +84,10 @@ const endpoints = {
|
|||
url: "/parts/api/v1/parts/supporting-items",
|
||||
method: "POST",
|
||||
},
|
||||
GetRecalPart: {
|
||||
url: "/parts/api/v1/parts/recal-parts",
|
||||
method: "GET",
|
||||
},
|
||||
GetAlertReasons: {
|
||||
url: "/location/api/v1/location/alert-reasons",
|
||||
method: "GET",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
};
|
||||
|
|
|
|||
|
|
@ -29,6 +29,19 @@ export function coverageStatusValue(intCoverageStatus) {
|
|||
}
|
||||
}
|
||||
|
||||
export function coverageStatusEnum(strCoverageStatus) {
|
||||
switch (strCoverageStatus) {
|
||||
case coverageStatus.PENDING:
|
||||
return 0;
|
||||
case coverageStatus.NOCOMP:
|
||||
return 1;
|
||||
case coverageStatus.VERIFIED:
|
||||
return 2;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export const coverageType = {
|
||||
NONE: "None",
|
||||
DEDUCTIBLE: "Deductible",
|
||||
|
|
@ -50,3 +63,18 @@ export function coverageTypeValue(intCoverageType) {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function coverageTypeEnum(strCoverageType) {
|
||||
switch (strCoverageType) {
|
||||
case coverageType.NONE:
|
||||
return 0;
|
||||
case coverageType.DEDUCTIBLE:
|
||||
return 1;
|
||||
case coverageType.ITAC:
|
||||
return 2;
|
||||
case coverageType.NOCOMP:
|
||||
return 3;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ const partTypeStrings = {
|
|||
FRONT_WIPER: "FRONT WIPER",
|
||||
REAR_WIPER: "REAR WIPER",
|
||||
RAIN_DEFENSE: "RAIN DEFENSE",
|
||||
ADAS_RECALIBRATION: "ADAS RECALIBRATION",
|
||||
RECALIBRATION: "RECALIBRATION",
|
||||
REPLACE_FEE: "REPLACE FEE",
|
||||
RECYCLE_FEE: "RECYCLE FEE",
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ const storeActions = {
|
|||
REVALIDATE_ORDER_PROMOS_AND_SAVE_SERVER_DATA: "revalidateOrderPromosAndSaveServerData",
|
||||
GET_INSURANCE_COMPANY_LIST: "getInsuranceCompanyList",
|
||||
GET_BILL_TO_ACCOUNT_NUMBER: "getBillToAccountNumber",
|
||||
GET_RECAL_PARTS_AND_SAVE_TO_LINE_ITEMS: "getRecalPartsAndSaveToLineItems",
|
||||
|
||||
// DEPENDENCY MUTATIONS
|
||||
RESET_DAMAGE_STATE_AND_DEPENDENCIES: "resetDamageAndDependencies",
|
||||
|
|
|
|||
|
|
@ -305,8 +305,8 @@ export default {
|
|||
if (!this.lineItems || this.lineItems.length < 1) return;
|
||||
|
||||
const lineItemsCopy = deepClone(this.lineItems);
|
||||
lineItemsCopy.supportingItems = lineItemsCopy.supportingItems
|
||||
? baseMixin.methods.filterOutRecalibration(lineItemsCopy?.supportingItems)
|
||||
lineItemsCopy.glassParts = lineItemsCopy.glassParts
|
||||
? baseMixin.methods.filterOutRecalibration(lineItemsCopy?.glassParts)
|
||||
: [];
|
||||
return lineItemsCopy;
|
||||
},
|
||||
|
|
@ -1007,6 +1007,11 @@ export default {
|
|||
},
|
||||
salesTax() {
|
||||
if (!this.lineItems || this.lineItems.length < 1) return;
|
||||
|
||||
if (this.isInsurance && !this.showCoverageAsVerified) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return this.isInsurance || !this.shouldHideRecalibration
|
||||
? baseMixin.methods.getSalesTax(this.lineItems) // calculate with recal (if on order)
|
||||
: baseMixin.methods.getSalesTax(this.lineItemsWithoutRecal); // calculated without recal
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export default {
|
|||
return this.leftAlignHeader ? "justify-content-start" : "justify-content-center";
|
||||
},
|
||||
subText() {
|
||||
return this.getCmsContent(this.cmsWidgetName, "HeaderSubText");
|
||||
return this.getCmsContent(this.cmsWidgetName, "SubheaderText");
|
||||
},
|
||||
backButtonAccessibleText() {
|
||||
return this.getCmsContent(this.cmsWidgetName, "BackButtonAccessibleText");
|
||||
|
|
|
|||
|
|
@ -109,8 +109,10 @@ export async function getImplicitNavigation(toRoute) {
|
|||
export async function navigateToHeritageFunnel({ shouldSaveSession, pageNameToLog }) {
|
||||
const log = getQuerystringParameter(queryStrings.LOG);
|
||||
if (eval(log)) {
|
||||
console.log("------------- Navigate to heritage start -----------------");
|
||||
console.log(new Date() + " applicationConfig: " + JSON.stringify(applicationConfig));
|
||||
console.log(new Date() + " navigateToHeritageFunnel: " + applicationConfig.HERITAGE_FUNNEL);
|
||||
console.log("------------- Navigate to heritage end -----------------");
|
||||
}
|
||||
|
||||
// Create the order (or save existing order) when navigating to Heritage Funnel.
|
||||
|
|
|
|||
52
src/helpers/recal-helper.js
Normal file
52
src/helpers/recal-helper.js
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import { deepClone } from "@/helpers/object-helper";
|
||||
import { partTypeStrings } from "@/constants/part-type-strings";
|
||||
|
||||
const recalPartTypes = [partTypeStrings.RECALIBRATION, partTypeStrings.ADAS_RECALIBRATION];
|
||||
|
||||
export function isRecalPartOrHasChildRecalPart(lineItem) {
|
||||
if (lineItem.childParts && lineItem.childParts.length > 0) {
|
||||
return isRecalPart(lineItem) || containsRecalParts(lineItem.childParts);
|
||||
} else {
|
||||
return isRecalPart(lineItem);
|
||||
}
|
||||
}
|
||||
|
||||
export function isRecalPart(lineItem) {
|
||||
return recalPartTypes.some((type) => lineItem.partType === type);
|
||||
}
|
||||
|
||||
export function containsRecalParts(lineItems) {
|
||||
if (!lineItems) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Array.isArray(lineItems)) {
|
||||
return lineItems.some((li) => isRecalPartOrHasChildRecalPart(li));
|
||||
} else {
|
||||
// complex object form -- flatten and re-call.
|
||||
const flattened = [
|
||||
...(lineItems.glassParts ?? []),
|
||||
...(lineItems.supportingItems ?? []),
|
||||
...(lineItems.vaps ?? []),
|
||||
...(lineItems.promos ?? []),
|
||||
];
|
||||
|
||||
return flattened.some((li) => isRecalPartOrHasChildRecalPart(li));
|
||||
}
|
||||
}
|
||||
|
||||
export function getItemsWithoutRecalParts(lineItems) {
|
||||
const copy = deepClone(lineItems);
|
||||
|
||||
const firstLevelFiltered = copy.filter((li) => !isRecalPart(li));
|
||||
|
||||
const childrenFiltered = firstLevelFiltered.map((li) => {
|
||||
if (li.childParts && li.childParts.length > 0) {
|
||||
li.childParts = getItemsWithoutRecalParts(li.childParts);
|
||||
}
|
||||
|
||||
return li;
|
||||
});
|
||||
|
||||
return childrenFiltered;
|
||||
}
|
||||
|
|
@ -60,6 +60,7 @@
|
|||
v-model="lineItems"
|
||||
:showAsPaid="isPia"
|
||||
servicePackageOptionsCmsName="ServicePackageTitle"
|
||||
:isInsurance="isInsurance"
|
||||
:insuranceDeductible="currentDeductible"
|
||||
:insuranceCompanyName="insuranceCompanyName"
|
||||
:showInsuranceCoverageAs="showInsuranceCoverageAs"
|
||||
|
|
@ -108,6 +109,7 @@ import { getDisplayTextForDurationLength } from "@/helpers/duration-length-helpe
|
|||
import { experimentSettings } from "@/constants/experiments";
|
||||
import { partTypeStrings } from "@/constants/part-type-strings";
|
||||
import { containsLineItemWithPartType } from "@/helpers/service-package-helper";
|
||||
import { containsRecalParts } from "@/helpers/recal-helper.js";
|
||||
|
||||
export default {
|
||||
name: "confirmation",
|
||||
|
|
@ -170,10 +172,7 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
isRecalibrationOnOrder() {
|
||||
return containsLineItemWithPartType(
|
||||
partTypeStrings.RECALIBRATION,
|
||||
this?.lineItems?.supportingItems
|
||||
);
|
||||
return containsRecalParts(this?.lineItems);
|
||||
},
|
||||
shouldHideRecalibration() {
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -153,6 +153,7 @@ import { partTypeStrings } from "@/constants/part-type-strings";
|
|||
import { mapTaxedLineItemsToStoreFormat } from "../../store";
|
||||
import { coverageStatus } from "@/constants/insurance";
|
||||
import { containsLineItemWithPartType } from "@/helpers/service-package-helper";
|
||||
import { containsRecalParts } from "@/helpers/recal-helper";
|
||||
|
||||
defineRule("payment-method-required", required(errorMessages.OPTION_REQUIRED));
|
||||
defineRule("recal-ack-required", required(errorMessages.RECAL_ACK_REQUIRED));
|
||||
|
|
@ -586,10 +587,11 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
isRecalibrationOnOrder() {
|
||||
return containsLineItemWithPartType(
|
||||
partTypeStrings.RECALIBRATION,
|
||||
this.$store.getters.order.lineItems?.supportingItems
|
||||
);
|
||||
const order = baseMixin.methods.hasSubmittedOrder()
|
||||
? baseMixin.methods.getSubmittedOrder()
|
||||
: this.$store.getters.order;
|
||||
|
||||
return containsRecalParts(order.lineItems);
|
||||
},
|
||||
shouldHideRecalibration() {
|
||||
return (
|
||||
|
|
@ -626,13 +628,16 @@ export default {
|
|||
},
|
||||
showInsuranceCoverageAs() {
|
||||
if (!this.isInsurance) return null;
|
||||
|
||||
if (this.isNoComp || this.isItac) {
|
||||
return coverageStatus.NOCOMP;
|
||||
} else {
|
||||
return this.hasSubmittedOrder()
|
||||
? this.getSubmittedOrder()?.payment.insuranceCoverage.coverageStatus
|
||||
: this.$store.getters.payment.insuranceCoverage.coverageStatus;
|
||||
}
|
||||
|
||||
if (this.$store.getters.coverageIsVerified) {
|
||||
return coverageStatus.VERIFIED;
|
||||
}
|
||||
|
||||
return coverageStatus.PENDING;
|
||||
},
|
||||
currentDeductible() {
|
||||
return this.hasSubmittedOrder()
|
||||
|
|
|
|||
|
|
@ -128,10 +128,14 @@ 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";
|
||||
import { containsRecalParts } from "@/helpers/recal-helper";
|
||||
defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
|
||||
|
||||
const INSURANCE_TAB_TO_DISPLAY_THRESHOLD_DEFAULT = 300;
|
||||
|
|
@ -396,9 +400,18 @@ export default {
|
|||
return Object.assign({}, this.lineItems);
|
||||
},
|
||||
isRecalibrationOnOrder() {
|
||||
return containsRecalParts(this.lineItems);
|
||||
},
|
||||
isServicePackageDiscountOnOrder() {
|
||||
return containsLineItemWithPartType(
|
||||
partTypeStrings.RECALIBRATION,
|
||||
this?.availableLineItems
|
||||
partTypeStrings.SERVICE_PACKAGE_DISCOUNT,
|
||||
this.availableLineItems
|
||||
);
|
||||
},
|
||||
servicePackageDiscountParts() {
|
||||
return findLineItemsWithPartType(
|
||||
partTypeStrings.SERVICE_PACKAGE_DISCOUNT,
|
||||
this.availableLineItems
|
||||
);
|
||||
},
|
||||
shouldHideRecalibration() {
|
||||
|
|
@ -425,7 +438,7 @@ export default {
|
|||
const payment = store.getters.order.payment;
|
||||
const log = getQuerystringParameter(queryStrings.LOG);
|
||||
if (eval(log)) {
|
||||
console.log("quote.vue pagePrereqs:");
|
||||
console.log("------------- quote.vue pagePrereqs start -----------------");
|
||||
console.log(
|
||||
new Date() +
|
||||
" store.getters.order.serviceLocation.zipCode: " +
|
||||
|
|
@ -451,6 +464,7 @@ export default {
|
|||
" store.getters.order.payment.insuranceCoverage?.isVerified: " +
|
||||
payment?.insuranceCoverage?.isVerified
|
||||
);
|
||||
console.log("----------------- quote.vue pagePrereqs end -----------------");
|
||||
}
|
||||
return (
|
||||
store.getters.order.serviceLocation.zipCode &&
|
||||
|
|
@ -563,6 +577,40 @@ 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 =
|
||||
baseMixin.methods.filterOutRecalibration(lineItemsToPrice);
|
||||
}
|
||||
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() {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import {
|
|||
getPromosWithAddableVaps,
|
||||
getLineItemsThatMatchPromos,
|
||||
} from "@/helpers/promotions-helper";
|
||||
import { containsRecalParts, getItemsWithoutRecalParts } from "@/helpers/recal-helper";
|
||||
|
||||
export default {
|
||||
name: "servicePackageQuestion",
|
||||
|
|
@ -239,9 +240,7 @@ export default {
|
|||
let lineItemsToPrice = [...this.nullSafeAvailableLineItems];
|
||||
|
||||
if (this.isRecalibrationOnOrder && this.shouldHideRecalibration) {
|
||||
lineItemsToPrice = lineItemsToPrice.filter((item) => {
|
||||
return item.partType != partTypeStrings.RECALIBRATION;
|
||||
});
|
||||
lineItemsToPrice = getItemsWithoutRecalParts(lineItemsToPrice);
|
||||
}
|
||||
|
||||
//remove service package discount part
|
||||
|
|
|
|||
|
|
@ -98,6 +98,9 @@ import store from "@/store";
|
|||
import { storeActions } from "@/constants/store-actions.js";
|
||||
import baseMixin from "@/mixins/base-mixin.js";
|
||||
import { getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
|
||||
import { applicationConfig } from "../../constants/application-config";
|
||||
import { queryStrings } from "@/constants/query-strings";
|
||||
import { getQuerystringParameter } from "@/helpers/querystring-helper";
|
||||
|
||||
//define validation rules
|
||||
defineRule("year-required", required(errorMessages.YEAR_REQUIRED));
|
||||
|
|
@ -127,6 +130,12 @@ export default {
|
|||
},
|
||||
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
const log = getQuerystringParameter(queryStrings.LOG);
|
||||
if (eval(log)) {
|
||||
console.log("----------------- applicationConfig start -----------------");
|
||||
console.log(new Date() + JSON.stringify(applicationConfig));
|
||||
console.log("----------------- applicationConfig end -----------------");
|
||||
}
|
||||
// Call APIs
|
||||
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
||||
const experimentForLogging = store.getters.applicationUser.experiments.find(
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { queryStrings } from "@/constants/query-strings";
|
|||
import { dynamicStrings } from "@/constants/dynamic-strings";
|
||||
import { partTypeStrings } from "../constants/part-type-strings";
|
||||
import { showFmgLoadingModal } from "@/helpers/loading-modal-helper";
|
||||
import { getItemsWithoutRecalParts } from "@/helpers/recal-helper";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
|
|
@ -82,7 +83,7 @@ export default {
|
|||
};
|
||||
},
|
||||
getTierOnePackagePrice(lineItems) {
|
||||
let lineItemsToPrice = lineItems.filter((lineItem) => {
|
||||
let lineItemsToPrice = lineItems?.filter((lineItem) => {
|
||||
return (
|
||||
lineItem.partType != partTypeStrings.FRONT_WIPER &&
|
||||
lineItem.partType != partTypeStrings.REAR_WIPER &&
|
||||
|
|
@ -94,7 +95,7 @@ export default {
|
|||
return totalPrice;
|
||||
},
|
||||
filterOutFees(lineItems) {
|
||||
const filteredLineItems = lineItems.filter((item) => {
|
||||
const filteredLineItems = lineItems?.filter((item) => {
|
||||
return (
|
||||
(!item.partType.includes("FEE") && !item.partType.includes("EARLY BIRD")) ||
|
||||
(item.partType === "REPAIR FEE" && item.partNumber != "SUPPLIES-REPAIR")
|
||||
|
|
@ -103,14 +104,11 @@ export default {
|
|||
return filteredLineItems;
|
||||
},
|
||||
filterOutRecalibration(lineItems) {
|
||||
const filteredLineItems = lineItems.filter((item) => {
|
||||
return !item.partType.includes(partTypeStrings.RECALIBRATION);
|
||||
});
|
||||
return filteredLineItems;
|
||||
return getItemsWithoutRecalParts(lineItems);
|
||||
},
|
||||
getTotalPriceOfAllLineItemsAndChildParts(lineItems, includeTax) {
|
||||
let totalPrice = 0;
|
||||
lineItems.forEach((lineItem) => {
|
||||
lineItems?.forEach((lineItem) => {
|
||||
totalPrice += this.getTotalLineItemPrice(lineItem, includeTax);
|
||||
if (lineItem.childParts) {
|
||||
totalPrice += this.getTotalPriceOfAllLineItemsAndChildParts(
|
||||
|
|
@ -141,41 +139,43 @@ export default {
|
|||
},
|
||||
getAmountDue(lineItems, includeTax = true) {
|
||||
var amountDue = 0;
|
||||
if (lineItems.glassParts) {
|
||||
if (lineItems?.glassParts) {
|
||||
amountDue += this.getTotalPriceOfAllLineItemsAndChildParts(
|
||||
lineItems.glassParts,
|
||||
includeTax
|
||||
);
|
||||
}
|
||||
if (lineItems.supportingItems) {
|
||||
|
||||
if (lineItems?.supportingItems) {
|
||||
amountDue += this.getTotalPriceOfAllLineItemsAndChildParts(
|
||||
lineItems.supportingItems,
|
||||
includeTax
|
||||
);
|
||||
}
|
||||
if (lineItems.vaps) {
|
||||
|
||||
const order = this.hasSubmittedOrder() ? this.getSubmittedOrder() : store.getters.order;
|
||||
if (
|
||||
store.getters.coverageIsVerified &&
|
||||
!order.policy.isNoComp &&
|
||||
!order.policy.isItac
|
||||
) {
|
||||
amountDue = order.policy.currentDeductible;
|
||||
}
|
||||
|
||||
if (lineItems?.vaps) {
|
||||
amountDue += this.getTotalPriceOfAllLineItemsAndChildParts(
|
||||
lineItems.vaps,
|
||||
includeTax
|
||||
);
|
||||
}
|
||||
if (lineItems.promos) {
|
||||
|
||||
if (lineItems?.promos) {
|
||||
amountDue += this.getTotalPriceOfAllLineItemsAndChildParts(
|
||||
lineItems.promos,
|
||||
includeTax
|
||||
);
|
||||
}
|
||||
|
||||
const order = this.hasSubmittedOrder() ? this.getSubmittedOrder() : store.getters.order;
|
||||
|
||||
if (
|
||||
order.payment.insuranceCoverage.isVerified &&
|
||||
!order.policy.isNoComp &&
|
||||
!order.policy.isItac
|
||||
) {
|
||||
amountDue += order.policy.currentDeductible;
|
||||
}
|
||||
|
||||
return ((amountDue * 100) / 100).toFixed(2);
|
||||
},
|
||||
getSubTotal(lineItems) {
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ describe("baseMixin.js", () => {
|
|||
promos: [],
|
||||
};
|
||||
|
||||
const payment = { insuranceCoverage: { isVerified: true } };
|
||||
const payment = { insuranceCoverage: { isVerified: false } };
|
||||
const policy = { isNoComp: false, isItac: false, currentDeductible: 250 };
|
||||
|
||||
store.getters = {
|
||||
|
|
@ -190,7 +190,7 @@ describe("baseMixin.js", () => {
|
|||
|
||||
var amtDue = mixIn.methods.getAmountDue(lineItems);
|
||||
|
||||
expect(amtDue).toEqual("303.00");
|
||||
expect(amtDue).toEqual("53.00");
|
||||
});
|
||||
|
||||
test("getAmountDue should function with a submitted order", () => {
|
||||
|
|
@ -223,7 +223,7 @@ describe("baseMixin.js", () => {
|
|||
promos: [],
|
||||
};
|
||||
|
||||
const payment = { insuranceCoverage: { isVerified: true } };
|
||||
const payment = { insuranceCoverage: { isVerified: false } };
|
||||
const policy = { isNoComp: false, isItac: false, currentDeductible: 250 };
|
||||
|
||||
mixIn.methods.hasSubmittedOrder = jest.fn().mockReturnValue(true);
|
||||
|
|
@ -240,7 +240,7 @@ describe("baseMixin.js", () => {
|
|||
|
||||
var amtDue = mixIn.methods.getAmountDue(lineItems);
|
||||
|
||||
expect(amtDue).toEqual("303.00");
|
||||
expect(amtDue).toEqual("53.00");
|
||||
});
|
||||
|
||||
test("getAmountDue for cash should sum lineitems", () => {
|
||||
|
|
|
|||
|
|
@ -450,7 +450,17 @@ export default {
|
|||
const collectedGlassParts = this.reducedGlassPartsArray(partsOrQuestions);
|
||||
|
||||
// save to store lineItems.glassParts
|
||||
self.dispatchStoreAction(storeActions.SAVE_GLASS_PARTS, collectedGlassParts, false);
|
||||
await self.dispatchStoreAction(
|
||||
storeActions.SAVE_GLASS_PARTS,
|
||||
collectedGlassParts,
|
||||
false
|
||||
);
|
||||
|
||||
await self.dispatchStoreActionWithLogging(
|
||||
storeActions.GET_RECAL_PARTS_AND_SAVE_TO_LINE_ITEMS,
|
||||
null,
|
||||
currentPage
|
||||
);
|
||||
|
||||
const payment = store.getters.payment;
|
||||
|
||||
|
|
|
|||
|
|
@ -36,9 +36,12 @@ import sharedMutations from "./vuex-shared-mutations/vuexSharedMutations";
|
|||
import {
|
||||
coverageStatus,
|
||||
coverageStatusValue,
|
||||
coverageStatusEnum,
|
||||
coverageType,
|
||||
coverageTypeValue,
|
||||
coverageTypeEnum,
|
||||
} from "@/constants/insurance";
|
||||
import { containsRecalParts } from "@/helpers/recal-helper";
|
||||
|
||||
// Export State
|
||||
const getDefaultState = () => {
|
||||
|
|
@ -772,6 +775,24 @@ export const getters = {
|
|||
);
|
||||
return !!nonWindshieldItems?.length;
|
||||
},
|
||||
coverageIsVerified: (state) => {
|
||||
let order;
|
||||
if (window.sessionStorage.getItem("submittedOrder") !== null) {
|
||||
order = JSON.parse(window.sessionStorage.getItem("submittedOrder"));
|
||||
} else {
|
||||
order = state.order;
|
||||
}
|
||||
|
||||
if (
|
||||
order.payment?.insuranceCoverage?.isVerified &&
|
||||
order.policy?.currentDeductible != 9999 &&
|
||||
order.policy?.currentDeductible != 7777
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
isMobileAppointment: (state) => {
|
||||
return state.order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE;
|
||||
},
|
||||
|
|
@ -897,13 +918,13 @@ export const getters = {
|
|||
isVerifiedAndDeductibleZeroConfirmed: (state) => {
|
||||
// used as a CMS variable on /payment-method, needed for FunnelSubHeaderWidget on cart pages
|
||||
if (
|
||||
(state.order.policy.currentDeductible === 0 ||
|
||||
state.order.policy.currentDeductible > 0) &&
|
||||
state.order.payment.insuranceCoverage.coverageStatus === coverageStatus.VERIFIED &&
|
||||
state.order.policy.currentDeductible === 0 &&
|
||||
getters.coverageIsVerified(state) &&
|
||||
!state.order.policy.isNoComp
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
requiresVerifiedRedirecting: (state) => {
|
||||
|
|
@ -1531,15 +1552,38 @@ export const actions = {
|
|||
},
|
||||
|
||||
getMobileFeePart(context, { pageNameToLog }) {
|
||||
const damageType = context.getters.damage.isRepair ? "Repair" : "Replace";
|
||||
const serviceType = context.getters.damage.isRepair ? "Repair" : "Install";
|
||||
const facilityType = "Mobile";
|
||||
const parentAccountNumber = context.getters.payment.parentAccountNumber;
|
||||
const billToAccountNumber = context.getters.payment.billToAccountNumber
|
||||
? context.getters.payment.billToAccountNumber
|
||||
: applicationConfig.CASH_DEFAULT_BILL_TO_ACCOUNT_NUMBER;
|
||||
|
||||
const order = context.getters.order;
|
||||
const coverageStatus = coverageStatusEnum(order.payment?.insuranceCoverage?.coverageStatus);
|
||||
const coverageType = coverageTypeEnum(order.payment?.insuranceCoverage?.coverageType);
|
||||
const isItacOptimized = order.policy?.isItac ?? false;
|
||||
const zipCode =
|
||||
order.serviceLocation?.provider?.address?.zipCode ?? order.serviceLocation?.zipCode;
|
||||
|
||||
var providerNumber =
|
||||
order.serviceLocation?.provider?.providerNumber ?? order.serviceLocation?.zipCodeCtu;
|
||||
if (providerNumber.startsWith("00") && providerNumber.length > 5) {
|
||||
providerNumber = providerNumber.substring(1);
|
||||
}
|
||||
|
||||
var endPoint = `${endpoints.GetMobileFeePart.url}/?serviceType=${serviceType}&facilityType=${facilityType}&parentAccountNumber=${parentAccountNumber}&billToAccountNumber=${billToAccountNumber}&providerNumber=${providerNumber}&isItacOptimized=${isItacOptimized}&zipCode=${zipCode}`;
|
||||
if (coverageStatus) {
|
||||
endPoint = `${endPoint}&coverageStatus=${coverageStatus}`;
|
||||
}
|
||||
|
||||
if (coverageType) {
|
||||
endPoint = `${endPoint}&coverageType=${coverageType}`;
|
||||
}
|
||||
|
||||
return globalMethods.callHttpClient({
|
||||
method: endpoints.GetMobileFeePart.method,
|
||||
endpoint: `${endpoints.GetMobileFeePart.url}/${damageType}/${parentAccountNumber}/${billToAccountNumber}`,
|
||||
endpoint: endPoint,
|
||||
logApiCall: true,
|
||||
pageNameToLog: pageNameToLog,
|
||||
});
|
||||
|
|
@ -2903,6 +2947,46 @@ export const actions = {
|
|||
externalParameterMMS.externalParameterStyle
|
||||
);
|
||||
},
|
||||
|
||||
async getRecalPartsAndSaveToLineItems(context, { pageNameToLog }) {
|
||||
// identify each part that needs recal
|
||||
const glassParts = context.state.order?.lineItems?.glassParts ?? [];
|
||||
|
||||
for (let i = 0; i < glassParts.length; i++) {
|
||||
// does this part need recal?
|
||||
const needsRecal =
|
||||
!!glassParts[i].requiresRecalibration && !!glassParts[i].recalibrationType;
|
||||
|
||||
if (needsRecal) {
|
||||
const recalType = glassParts[i].recalibrationType;
|
||||
const parentAccountNumber =
|
||||
context.state.order.payment.parentAccountNumber ??
|
||||
applicationConfig.CASH_PARENT_ACCOUNT_NUMBER;
|
||||
|
||||
// Get part from API
|
||||
const urlExtension = `${context.state.order.vehicle.carId}/${glassParts[i].partNumber}/${recalType}/${parentAccountNumber}/${context.state.order.serviceLocation.zipCode}/${applicationConfig.ANALYTICS_APPLICATION_NAME}/${context.state.order.referralSequenceNumber}`;
|
||||
|
||||
const recalPartResponse = await globalMethods.callHttpClient({
|
||||
method: endpoints.GetRecalPart.method,
|
||||
endpoint: `${endpoints.GetRecalPart.url}/${urlExtension}`,
|
||||
payload: {},
|
||||
pageNameToLog: pageNameToLog,
|
||||
});
|
||||
|
||||
// If any parts retrieved, add as children to the glass part.
|
||||
if (
|
||||
recalPartResponse.status === 200 &&
|
||||
recalPartResponse.data.recalibrationParts?.length > 0
|
||||
) {
|
||||
if (!glassParts[i].childParts) {
|
||||
glassParts[i].childParts = [];
|
||||
}
|
||||
|
||||
glassParts[i].childParts.push(...recalPartResponse.data.recalibrationParts);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default createStore({
|
||||
|
|
@ -2925,34 +3009,7 @@ export default createStore({
|
|||
// Private Functions
|
||||
|
||||
function getHasRecalibrationPart(state) {
|
||||
var hasRequiresRecalibration =
|
||||
getNonFalseValuesOfPropertyInArrayOfObjects(
|
||||
state.order.lineItems.glassParts,
|
||||
"requiresRecalibration"
|
||||
)?.length > 0;
|
||||
var hasRecalibrationType =
|
||||
getNonFalseValuesOfPropertyInArrayOfObjects(
|
||||
state.order.lineItems.glassParts,
|
||||
"recalibrationType"
|
||||
)?.length > 0;
|
||||
|
||||
if (hasRequiresRecalibration) {
|
||||
if (hasRecalibrationType) {
|
||||
// Has both 'requiresRecalibration' and 'recalibrationType' and 'recalibrationType'
|
||||
return (
|
||||
getNonFalseValuesOfPropertyInArrayOfObjects(
|
||||
state.order.lineItems.glassParts,
|
||||
"recalibrationType"
|
||||
)[0].toLowerCase() != "unknown"
|
||||
);
|
||||
} else {
|
||||
// Has 'requiresRecalibration' but no 'recalibrationType' at all
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// Does not have 'requiresRecalibration'
|
||||
return false;
|
||||
}
|
||||
return containsRecalParts(state.order.lineItems);
|
||||
}
|
||||
|
||||
function sortArrayOfObjectsByPropertyValue(arrayOfObjects, propertyName) {
|
||||
|
|
|
|||
|
|
@ -3950,6 +3950,111 @@ describe("Getters", () => {
|
|||
mutations.updateVaps(storeState, mockStateValues.funnelVaps);
|
||||
mutations.updateGlassToReplace(storeState, mockStateValues.glassToReplace);
|
||||
|
||||
//Assert
|
||||
expect(getters.experimentOrder(storeState)).toEqual({
|
||||
funnelVehicleYear: mockStateValues.vehicleYear,
|
||||
funnelVehicleMake: mockStateValues.vehicleMake,
|
||||
funnelVehicleModel: mockStateValues.vehicleModel,
|
||||
funnelVehicleStyle: mockStateValues.vehicleStyle,
|
||||
funnelIsRepair: mockStateValues.isRepair,
|
||||
funnelNumberOfChips: mockStateValues.numberOfChips,
|
||||
funnelCarId: mockStateValues.carId,
|
||||
funnelServiceCity: mockStateValues.serviceCity,
|
||||
funnelServiceState: mockStateValues.serviceState,
|
||||
funnelServiceZipCode: mockStateValues.serviceZipCode,
|
||||
funnelParentAccountNumber: mockStateValues.parentAccountNumber,
|
||||
funnelIsCoverageVerified: mockStateValues.isCoverageVerified,
|
||||
funnelOrderPartNumbers: ["WINDSHIELDPARTNUMBER"],
|
||||
funnelOrderPartTypes: ["ADAS, maybe"],
|
||||
funnelHasRecalibrationPart: false,
|
||||
funnelSelectedMultiGlass: false,
|
||||
funnelSelectedWindshieldGlass: true,
|
||||
funnelSelectedBackGlass: false,
|
||||
funnelSelectedDriverSideGlass: false,
|
||||
funnelSelectedPassengerSideGlass: false,
|
||||
funnelProviderNumber: mockStateValues.funnelProviderNumber,
|
||||
funnelReferralType: mockStateValues.funnelReferralType,
|
||||
funnelServiceZipCodeCtu: mockStateValues.funnelServiceZipCodeCtu,
|
||||
});
|
||||
});
|
||||
|
||||
test("Single windshield with recalibration child part > return correct experimentOrder values", () => {
|
||||
// Arrange
|
||||
const storeState = state;
|
||||
const mockStateValues = {
|
||||
vehicleYear: 1000,
|
||||
vehicleMake: "CarMake",
|
||||
vehicleModel: "CarModel",
|
||||
vehicleStyle: "SuperCoolStyle",
|
||||
isRepair: false,
|
||||
numberOfChips: 0,
|
||||
carId: "Gibberish",
|
||||
serviceCity: "Columbus",
|
||||
serviceState: "OH-IO",
|
||||
serviceZipCode: 43215,
|
||||
parentAccountNumber: "999999",
|
||||
isCoverageVerified: false,
|
||||
glassParts: [
|
||||
{
|
||||
partNumber: "WINDSHIELDPARTNUMBER",
|
||||
description: "This is a windshield",
|
||||
recalibrationType: "ADAS, maybe",
|
||||
requiresRecalibration: true,
|
||||
requiresCapabilityQuestions: false,
|
||||
childParts: [
|
||||
{
|
||||
partNumber: "THIRD RECAL",
|
||||
description: "Additional Static Recal",
|
||||
recalibrationType:
|
||||
"DUAL & RECAL THIRD & HC FUNCTION TEST & RL SENSOR",
|
||||
ribCode: "RL",
|
||||
safelitePartNumber: "THIRD RECAL",
|
||||
status: "ACTIVE",
|
||||
partType: "ADAS RECALIBRATION",
|
||||
childParts: [],
|
||||
recalibrationFees: [],
|
||||
salesTax: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
otherParts: [],
|
||||
glassToReplace: [
|
||||
{
|
||||
glassLocation: "Windshield",
|
||||
glassName: "Single",
|
||||
},
|
||||
],
|
||||
funnelProviderNumber: "1",
|
||||
funnelReferralType: "CASH QUOTE",
|
||||
funnelServiceZipCodeCtu: "11111",
|
||||
};
|
||||
|
||||
//Act
|
||||
mutations.updateYear(storeState, mockStateValues.vehicleYear);
|
||||
mutations.updateMake(storeState, mockStateValues.vehicleMake);
|
||||
mutations.updateModel(storeState, mockStateValues.vehicleModel);
|
||||
mutations.updateStyle(storeState, mockStateValues.vehicleStyle);
|
||||
mutations.updateIsRepair(storeState, mockStateValues.isRepair);
|
||||
mutations.updateNumberOfChips(storeState, mockStateValues.numberOfChips);
|
||||
mutations.updateCarId(storeState, mockStateValues.carId);
|
||||
mutations.updateServiceLocation(storeState, {
|
||||
city: mockStateValues.serviceCity,
|
||||
state: mockStateValues.serviceState,
|
||||
zipCode: mockStateValues.serviceZipCode,
|
||||
zipCodeCtu: mockStateValues.funnelServiceZipCodeCtu,
|
||||
provider: {
|
||||
providerNumber: mockStateValues.funnelProviderNumber,
|
||||
},
|
||||
});
|
||||
mutations.updateParentAcctNumber(storeState, mockStateValues.parentAccountNumber);
|
||||
mutations.updateInsuranceVerifiedStatus(storeState, mockStateValues.isCoverageVerified);
|
||||
mutations.updateIsInsurance(storeState, false);
|
||||
mutations.updateGlassParts(storeState, mockStateValues.glassParts);
|
||||
mutations.updateSupportingItems(storeState, mockStateValues.funnelSupportingItems);
|
||||
mutations.updateVaps(storeState, mockStateValues.funnelVaps);
|
||||
mutations.updateGlassToReplace(storeState, mockStateValues.glassToReplace);
|
||||
|
||||
//Assert
|
||||
expect(getters.experimentOrder(storeState)).toEqual({
|
||||
funnelVehicleYear: mockStateValues.vehicleYear,
|
||||
|
|
|
|||
Loading…
Reference in a new issue