Providers are now grouped for in-shop They can accept ranges up to 180 but that is not needed yet
4692 lines
187 KiB
JavaScript
4692 lines
187 KiB
JavaScript
import { createStore } from "vuex";
|
|
import { endpoints } from "@/constants/endpoints.js";
|
|
import { storeMutations } from "@/constants/store-mutations";
|
|
import { sessionStorageKeyConstants } from "@/constants/session-storage.js";
|
|
import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/session-helper";
|
|
import createPersistedState from "vuex-persistedstate";
|
|
import globalMethods from "@/global-methods";
|
|
import { storeActions } from "@/constants/store-actions";
|
|
import { applicationConfig } from "@/constants/application-config";
|
|
import { experimentTriggers } from "@/constants/experiments";
|
|
import { damageLocationsSelected } from "@/constants/damage-locations-selected";
|
|
import { routeData } from "@/router/constants/routes";
|
|
import {
|
|
deleteFunnelCookie,
|
|
getSessionIdValue,
|
|
getDeviceIdValue,
|
|
} from "@/helpers/heritage-integration/cookie-helper.js";
|
|
import { deepEqual } from "@/helpers/object-helper";
|
|
import baseMixin from "@/mixins/base-mixin.js";
|
|
import {
|
|
AppointmentTypeStrings,
|
|
PREMIUM_FEE_PART_TYPE,
|
|
RouteCodeFlags,
|
|
} from "@/constants/schedule-constants";
|
|
import { getQuerystringParameter } from "@/helpers/querystring-helper";
|
|
import { deepClone } from "@/helpers/object-helper";
|
|
import {
|
|
getExperimentSettingsFromExperimentList,
|
|
hasSettingEqualTo,
|
|
} from "../helpers/experiment-helper";
|
|
import { queryStrings } from "@/constants/query-strings";
|
|
import { partTypeStrings } from "@/constants/part-type-strings";
|
|
import {
|
|
convertDateStringToDate,
|
|
militaryToTwelveHourTime,
|
|
} from "@/layouts/schedule/helpers/schedule-helper";
|
|
import { getDisplayTextForDurationLength } from "@/helpers/duration-length-helper";
|
|
import { paymentMethods } from "@/constants/payment-method-constants";
|
|
import {
|
|
getPromoCodeWithoutBundleIdentifier,
|
|
removeCurrentlyActivePromoCodesFromInactivePromos,
|
|
} from "@/helpers/promotions-helper";
|
|
import { getDateDifferenceInDays, normalizeDotNetMinDate } from "@/helpers/date-helper";
|
|
import sharedMutations from "./vuex-shared-mutations/vuexSharedMutations";
|
|
import {
|
|
coverageStatus,
|
|
coverageStatusValue,
|
|
coverageStatusEnum,
|
|
coverageType,
|
|
coverageTypeValue,
|
|
coverageTypeEnum,
|
|
} from "@/constants/insurance";
|
|
import {
|
|
containsRecalParts,
|
|
getTopLevelPartsWithRecal,
|
|
isRecalPartOrHasChildRecalPart,
|
|
getRecalPartNumbers,
|
|
} from "@/helpers/recal-helper";
|
|
import { externalParameterStatus } from "@/constants/external-parameters";
|
|
import { experimentSettings } from "@/constants/experiments";
|
|
import { addPricesToLineItems, getAmountDue } from "@/helpers/pricing-helper";
|
|
|
|
// Export State
|
|
const getDefaultState = () => {
|
|
return {
|
|
order: {
|
|
vehicle: {
|
|
year: null,
|
|
make: null,
|
|
model: null,
|
|
style: null,
|
|
vehicleSubType: null,
|
|
vehicleSpecialClass: null,
|
|
isBigTruck: false,
|
|
carId: null,
|
|
category: null,
|
|
vin: null,
|
|
canSafeliteService: null,
|
|
imageUrl: null,
|
|
imageVifNumber: null,
|
|
imageColor: null,
|
|
registration: {
|
|
licensePlate: null,
|
|
},
|
|
skipVINLookup: false,
|
|
skipPartQuestions: false,
|
|
vinRequired: false,
|
|
},
|
|
serviceLocation: {
|
|
address: null,
|
|
address2: null,
|
|
city: null,
|
|
state: null,
|
|
zipCode: null,
|
|
zipCodeCtu: null,
|
|
appointmentType: null,
|
|
isVehicleProtected: null,
|
|
provider: {
|
|
providerNumber: null,
|
|
address: {
|
|
streetAddress: null,
|
|
city: null,
|
|
state: null,
|
|
zipCode: null,
|
|
zipCodeCtu: null,
|
|
},
|
|
},
|
|
techNotes: null,
|
|
},
|
|
customer: {
|
|
firstName: null,
|
|
lastName: null,
|
|
emailAddress: null,
|
|
phoneNumber: null,
|
|
isSmsOptIn: null,
|
|
waitListRequested: null,
|
|
address: {
|
|
streetAddress: null,
|
|
streetAddress2: null,
|
|
city: null,
|
|
state: null,
|
|
zipCode: null,
|
|
},
|
|
},
|
|
damage: {
|
|
isRepair: null,
|
|
numberOfChips: null,
|
|
glassToReplace: null,
|
|
partQuestionAnswers: null,
|
|
moldingQuestionAnswers: null,
|
|
capabilityQuestionAnswers: null,
|
|
dateOfLoss: null,
|
|
damageCause: null,
|
|
installOemGlass: null,
|
|
},
|
|
lineItems: {
|
|
glassParts: null,
|
|
supportingItems: null,
|
|
vaps: null,
|
|
serverData: null,
|
|
promos: null,
|
|
},
|
|
payment: {
|
|
isInsurance: null,
|
|
insuranceCoverage: {
|
|
isVerified: null,
|
|
coverageStatus: null,
|
|
coverageSubStatus: null,
|
|
coverageType: null,
|
|
coverageVerificationType: null,
|
|
claimNumber: null,
|
|
},
|
|
parentAccountNumber: 0,
|
|
accountName: null,
|
|
isClaimAndCoverage: false,
|
|
canScheduleOnline: false,
|
|
isManagedAccount: false,
|
|
billToAccountNumber: null,
|
|
isPia: null,
|
|
piaType: null,
|
|
inactivePromos: null,
|
|
paypalToken: null,
|
|
nextGenSettledAmount: 0,
|
|
ccToken: {
|
|
subscriptionId: null,
|
|
expMonth: null,
|
|
expYear: null,
|
|
cardType: null,
|
|
billToPostalCode: null,
|
|
billToFirstName: null,
|
|
billToLastName: null,
|
|
referenceNumber: null,
|
|
authCode: null,
|
|
transactionId: null,
|
|
transReferenceNumber: null,
|
|
lastFour: null,
|
|
},
|
|
},
|
|
policy: {
|
|
currentDeductible: 0,
|
|
originalDeductible: 0,
|
|
policyNumber: null,
|
|
isItac: false,
|
|
additionalAuthFlag: null,
|
|
isNoComp: false,
|
|
insuranceCompanyName: null,
|
|
phoneNumber: null,
|
|
phoneExtension: null,
|
|
dateOfBirth: null,
|
|
lossTime: null,
|
|
lossLocation: null,
|
|
lastName: null,
|
|
subrogation: null,
|
|
},
|
|
schedule: {
|
|
date: null,
|
|
startTime: null,
|
|
endTime: null,
|
|
routeCode: null,
|
|
jobMaxMinutes: null,
|
|
jobMinMinutes: null,
|
|
},
|
|
referralNumber: null,
|
|
referralSequenceNumber: null,
|
|
referralDate: null,
|
|
referralCorrelationId: null,
|
|
eon: null,
|
|
workOrderNumber: null,
|
|
workOrderId: null,
|
|
customerPortalLoginToken: null,
|
|
lockToken: null,
|
|
settledTenderAmount: 0,
|
|
isRecalAckOptIn: false,
|
|
isRecalAcknowledgedForScheduling: "",
|
|
isMSRFeeApplicable: false,
|
|
isMSRFeeCoveredByInsurance: false,
|
|
isNewInsuranceFlow: false,
|
|
},
|
|
applicationUser: {
|
|
eventBus: [],
|
|
pageData: {},
|
|
savedSessionTimeout: getDateForSavedSessionTimeout(),
|
|
saveSessionPromise: null,
|
|
savedSessionId: null,
|
|
crmCustomerId: null,
|
|
lastPageVisited: null,
|
|
experiments: [],
|
|
triggeredSiteEntry: false,
|
|
affiliateCookies: [],
|
|
loggingOption: false,
|
|
hasAlreadyTriggeredError: false,
|
|
},
|
|
idempotencyKeyFields: {
|
|
referralCorrelationId: null,
|
|
totalInCents: 0,
|
|
expiryTime: null,
|
|
idempotencyKey: null,
|
|
},
|
|
submittedStateRevision: 0,
|
|
};
|
|
};
|
|
|
|
export const state = getDefaultState();
|
|
export const externalParameterState = getExternalParameterDefaultState();
|
|
// Export Mutations
|
|
export const mutations = {
|
|
// VEHICLE MUTATIONS
|
|
updateYear(state, year) {
|
|
state.order.vehicle.year = year;
|
|
},
|
|
updateMake(state, make) {
|
|
state.order.vehicle.make = make;
|
|
},
|
|
updateModel(state, model) {
|
|
state.order.vehicle.model = model;
|
|
},
|
|
updateStyle(state, style) {
|
|
state.order.vehicle.style = style;
|
|
},
|
|
updateVehicleSubType(state, vehicleSubType) {
|
|
state.order.vehicle.vehicleSubType = vehicleSubType;
|
|
},
|
|
updateVehicleSpecialClass(state, vehicleSpecialClass) {
|
|
state.order.vehicle.vehicleSpecialClass = vehicleSpecialClass;
|
|
},
|
|
updateIsBigTruck(state, isBigTruck) {
|
|
state.order.vehicle.isBigTruck = isBigTruck;
|
|
},
|
|
updateCarId(state, carId) {
|
|
state.order.vehicle.carId = carId;
|
|
},
|
|
updateVehicleCategory(state, category) {
|
|
state.order.vehicle.category = category;
|
|
},
|
|
updateVehicleCanSafeliteService(state, canSafeliteService) {
|
|
state.order.vehicle.canSafeliteService = canSafeliteService;
|
|
},
|
|
updateSkipVINLookup(state, skipVINLookup) {
|
|
state.order.vehicle.skipVINLookup = skipVINLookup;
|
|
},
|
|
updateVinRequired(state, vinRequired) {
|
|
state.order.vehicle.vinRequired = vinRequired;
|
|
},
|
|
updateSkipPartQuestions(state, skipPartQuestions) {
|
|
state.order.vehicle.skipPartQuestions = skipPartQuestions;
|
|
},
|
|
updateSkipCapabilitiesQuestions(state, skipCapabilitiesQuestions) {
|
|
state.order.vehicle.skipCapabilitiesQuestions = skipCapabilitiesQuestions;
|
|
},
|
|
updateVehicleImageUrl(state, imageUrl) {
|
|
state.order.vehicle.imageUrl = imageUrl;
|
|
},
|
|
updateVehicleImageVifNumber(state, imageVifNumber) {
|
|
state.order.vehicle.imageVifNumber = imageVifNumber;
|
|
},
|
|
updateVehicleImageColor(state, imageColor) {
|
|
state.order.vehicle.imageColor = imageColor;
|
|
},
|
|
updateVehicleVin(state, vin) {
|
|
state.order.vehicle.vin = vin;
|
|
},
|
|
updateIsRepair(state, isRepair) {
|
|
state.order.damage.isRepair = isRepair;
|
|
},
|
|
updateNumberOfChips(state, numberOfChips) {
|
|
state.order.damage.numberOfChips = numberOfChips;
|
|
},
|
|
updateGlassToReplace(state, glassToReplace) {
|
|
state.order.damage.glassToReplace = glassToReplace;
|
|
},
|
|
updatePartQuestionAnswers(state, answersArray) {
|
|
state.order.damage.partQuestionAnswers = answersArray;
|
|
},
|
|
updateMoldingQuestionAnswers(state, answersArray) {
|
|
state.order.damage.moldingQuestionAnswers = answersArray;
|
|
},
|
|
updateCapabilityQuestionAnswers(state, answersArray) {
|
|
state.order.damage.capabilityQuestionAnswers = answersArray;
|
|
},
|
|
updateGlassParts(state, partsData) {
|
|
state.order.lineItems.glassParts = partsData;
|
|
},
|
|
updateVaps(state, partsData) {
|
|
state.order.lineItems.vaps = partsData;
|
|
},
|
|
updateSupportingItems(state, partsData) {
|
|
state.order.lineItems.supportingItems = partsData;
|
|
},
|
|
updateLineItemsServerData(state, serverData) {
|
|
state.order.lineItems.serverData = serverData;
|
|
},
|
|
updateInactivePromos(state, inactivePromos) {
|
|
state.order.payment.inactivePromos = inactivePromos;
|
|
},
|
|
updatePromos(state, promos) {
|
|
state.order.lineItems.promos = promos;
|
|
},
|
|
updatePageData(state, pageData) {
|
|
state.applicationUser.pageData[pageData.page] = pageData.data;
|
|
},
|
|
updateReferralCorrelationId(state, referralCorrelationId) {
|
|
state.order.referralCorrelationId = referralCorrelationId;
|
|
},
|
|
updateReferralNumber(state, referralNumber) {
|
|
state.order.referralNumber = referralNumber;
|
|
},
|
|
updateReferralSequenceNumber(state, referralSequenceNumber) {
|
|
state.order.referralSequenceNumber = referralSequenceNumber;
|
|
},
|
|
updateReferralDate(state, referralDate) {
|
|
state.order.referralDate = referralDate;
|
|
},
|
|
updateParentAcctNumber(state, parentAcctNumber) {
|
|
state.order.payment.parentAccountNumber = parentAcctNumber;
|
|
},
|
|
updateAccountName(state, accountName) {
|
|
state.order.payment.accountName = accountName;
|
|
state.order.policy.insuranceCompanyName = accountName;
|
|
},
|
|
updatePhoneNumber(state, phoneNumber) {
|
|
state.order.policy.phoneNumber = phoneNumber;
|
|
},
|
|
updatePhoneExtension(state, phoneExtension) {
|
|
state.order.policy.phoneExtension = phoneExtension;
|
|
},
|
|
updateStreetAddress(state, streetAddress) {
|
|
state.order.customer.address.streetAddress = streetAddress;
|
|
},
|
|
updateStreetAddress2(state, streetAddress2) {
|
|
state.order.customer.address.streetAddress2 = streetAddress2;
|
|
},
|
|
updateCity(state, city) {
|
|
state.order.customer.address.city = city;
|
|
},
|
|
updateState(state, stateValue) {
|
|
state.order.customer.address.state = stateValue;
|
|
},
|
|
updateZipCode(state, zipCode) {
|
|
state.order.customer.address.zipCode = zipCode;
|
|
},
|
|
updateClaimNumber(state, claimNumber) {
|
|
state.order.payment.insuranceCoverage.claimNumber = claimNumber;
|
|
},
|
|
updateIsClaimAndCoverage(state, isClaimAndCoverage) {
|
|
state.order.payment.isClaimAndCoverage = isClaimAndCoverage;
|
|
},
|
|
updateCanScheduleOnline(state, canScheduleOnline) {
|
|
state.order.payment.canScheduleOnline = canScheduleOnline;
|
|
},
|
|
updateIsManagedAccount(state, isManagedAccount) {
|
|
state.order.payment.isManagedAccount = isManagedAccount;
|
|
},
|
|
updateBillToAcctNumber(state, billToAcctNumber) {
|
|
state.order.payment.billToAccountNumber = billToAcctNumber;
|
|
},
|
|
updateEON(state, eon) {
|
|
state.order.eon = eon;
|
|
},
|
|
updateIsInsurance(state, isInsurance) {
|
|
state.order.payment.isInsurance = isInsurance;
|
|
},
|
|
resetInsuranceDetails(state) {
|
|
state.order.payment.insuranceCoverage = {
|
|
isVerified: null,
|
|
coverageStatus: null,
|
|
coverageSubStatus: null,
|
|
coverageType: null,
|
|
coverageVerificationType: null,
|
|
};
|
|
|
|
state.order.policy.policyNumber = null;
|
|
state.order.payment.insuranceCoverage.claimNumber = null;
|
|
state.order.policy.insuranceCompanyName = null;
|
|
state.order.customer.address.streetAddress = null;
|
|
state.order.customer.address.streetAddress2 = null;
|
|
state.order.customer.address.city = null;
|
|
state.order.customer.address.state = null;
|
|
state.order.customer.address.zipCode = null;
|
|
state.order.damage.dateOfLoss = null;
|
|
state.order.damage.damageCause = null;
|
|
},
|
|
updateIsPia(state, isPia) {
|
|
state.order.payment.isPia = isPia;
|
|
},
|
|
updatePiaType(state, piaType) {
|
|
state.order.payment.piaType = piaType;
|
|
},
|
|
updateWorkOrderNumber(state, workOrderNumber) {
|
|
state.order.workOrderNumber = workOrderNumber;
|
|
},
|
|
updateWorkOrderId(state, workOrderId) {
|
|
state.order.workOrderId = workOrderId;
|
|
},
|
|
updateCustomerPortalLoginToken(state, customerPortalLoginToken) {
|
|
state.order.customerPortalLoginToken = customerPortalLoginToken;
|
|
},
|
|
updateLockToken(state, lockToken) {
|
|
state.order.lockToken = lockToken;
|
|
},
|
|
updateSettledTenderAmount(state, settledTenderAmount) {
|
|
state.order.settledTenderAmount = settledTenderAmount;
|
|
},
|
|
updateIsRecalAckOptIn(state, isRecalAckOptIn) {
|
|
state.order.isRecalAckOptIn = isRecalAckOptIn;
|
|
},
|
|
updateIsRecalAcknowledgedForScheduling(state, isRecalAcknowledgedForScheduling) {
|
|
state.order.isRecalAcknowledgedForScheduling = isRecalAcknowledgedForScheduling;
|
|
},
|
|
updateIsOemGlassSelected(state, isOemGlassSelected) {
|
|
state.order.damage.installOemGlass = isOemGlassSelected;
|
|
},
|
|
updateIsMSRFeeApplicable(state, isMSRFeeApplicable) {
|
|
state.order.isMSRFeeApplicable = isMSRFeeApplicable;
|
|
},
|
|
updateIsMSRFeeCoveredByInsurance(state, isMSRFeeCoveredByInsurance) {
|
|
state.order.isMSRFeeCoveredByInsurance = isMSRFeeCoveredByInsurance;
|
|
},
|
|
updateIsNewInsuranceFlow(state, isNewInsuranceFlow) {
|
|
state.order.isNewInsuranceFlow = isNewInsuranceFlow;
|
|
},
|
|
updateCashPriceSubTotal(state, cashPriceSubTotal) {
|
|
state.order.cashPriceSubTotal =
|
|
cashPriceSubTotal === "" ? null : cashPriceSubTotal.toString();
|
|
},
|
|
updateCCToken(state, ccToken) {
|
|
state.order.payment.ccToken.subscriptionId = ccToken.subscriptionId;
|
|
state.order.payment.ccToken.expMonth = ccToken.expMonth;
|
|
state.order.payment.ccToken.expYear = ccToken.expYear;
|
|
state.order.payment.ccToken.cardType = ccToken.cardType;
|
|
state.order.payment.ccToken.billToPostalCode = ccToken.billToPostalCode;
|
|
state.order.payment.ccToken.billToFirstName = ccToken.billToFirstName;
|
|
state.order.payment.ccToken.billToLastName = ccToken.billToLastName;
|
|
state.order.payment.ccToken.referenceNumber = ccToken.referenceNumber;
|
|
state.order.payment.ccToken.authCode = ccToken.authCode;
|
|
state.order.payment.ccToken.transactionId = ccToken.transactionId;
|
|
state.order.payment.ccToken.transReferenceNumber = ccToken.transReferenceNumber;
|
|
state.order.payment.ccToken.lastFour = ccToken.lastFour;
|
|
},
|
|
updatePaypalToken(state, ppToken) {
|
|
state.order.payment.paypalToken = ppToken;
|
|
},
|
|
updateNextGenSettledAmount(state, nextGenSettledAmount) {
|
|
state.order.payment.nextGenSettledAmount = nextGenSettledAmount;
|
|
},
|
|
updateInsuranceVerifiedStatus(state, isVerified) {
|
|
state.order.payment.insuranceCoverage.isVerified = isVerified;
|
|
},
|
|
updateCustomerEmailAddress(state, customerEmailAddress) {
|
|
state.order.customer.emailAddress = customerEmailAddress;
|
|
},
|
|
updateCustomerPhoneNumber(state, phoneNumber) {
|
|
state.order.customer.phoneNumber = phoneNumber;
|
|
},
|
|
updateCustomerIsSmsOptin(state, isSmsOptIn) {
|
|
state.order.customer.isSmsOptIn = isSmsOptIn;
|
|
},
|
|
updateCustomerWaitListRequested(state, waitListRequested) {
|
|
state.order.customer.waitListRequested = waitListRequested;
|
|
},
|
|
updateVehicle(state, vehicleInfo) {
|
|
state.order.vehicle.year = vehicleInfo.year;
|
|
state.order.vehicle.make = vehicleInfo.make;
|
|
state.order.vehicle.model = vehicleInfo.model;
|
|
state.order.vehicle.style = vehicleInfo.style;
|
|
state.order.vehicle.carId = vehicleInfo.carId;
|
|
state.order.vehicle.category = vehicleInfo.category;
|
|
state.order.vehicle.vin = vehicleInfo.vin;
|
|
if (vehicleInfo.vinRequired !== undefined) {
|
|
state.order.vehicle.vinRequired = vehicleInfo.vinRequired;
|
|
}
|
|
|
|
state.order.vehicle.imageUrl = vehicleInfo.imageUrl;
|
|
state.order.vehicle.imageVifNumber = vehicleInfo.imageVifNumber;
|
|
state.order.vehicle.imageColor = vehicleInfo.imageVifColor;
|
|
},
|
|
updateRegistration(state, registrationInfo) {
|
|
state.order.vehicle.registration.licensePlate = registrationInfo?.licensePlate;
|
|
},
|
|
updateServiceZip(state, serviceZipInfo) {
|
|
state.order.serviceLocation.state = serviceZipInfo.state || serviceZipInfo.payload?.state;
|
|
state.order.serviceLocation.zipCode =
|
|
serviceZipInfo.zipCode || serviceZipInfo.payload?.zipCode;
|
|
state.order.serviceLocation.zipCodeCtu =
|
|
serviceZipInfo.zipCodeCtu || serviceZipInfo.payload?.zipCodeCtu;
|
|
},
|
|
updateServiceLocation(state, serviceLocationInfo) {
|
|
state.order.serviceLocation.address = serviceLocationInfo.address;
|
|
state.order.serviceLocation.address2 = serviceLocationInfo.address2;
|
|
state.order.serviceLocation.city = serviceLocationInfo.city;
|
|
state.order.serviceLocation.state = serviceLocationInfo.state;
|
|
state.order.serviceLocation.zipCode = serviceLocationInfo.zipCode;
|
|
state.order.serviceLocation.zipCodeCtu = serviceLocationInfo.zipCodeCtu;
|
|
state.order.serviceLocation.appointmentType = serviceLocationInfo.appointmentType;
|
|
state.order.serviceLocation.isVehicleProtected = serviceLocationInfo.isVehicleProtected;
|
|
|
|
state.order.serviceLocation.provider = {
|
|
providerNumber: serviceLocationInfo.provider?.providerNumber,
|
|
address: {
|
|
streetAddress: serviceLocationInfo.provider?.address?.streetAddress,
|
|
city: serviceLocationInfo.provider?.address?.city,
|
|
state: serviceLocationInfo.provider?.address?.state,
|
|
zipCode: serviceLocationInfo.provider?.address?.zipCode,
|
|
zipCodeCtu: serviceLocationInfo.provider?.address?.zipCodeCtu,
|
|
},
|
|
};
|
|
},
|
|
updateMobileDetails(state, mobileDetails) {
|
|
state.order.serviceLocation.address = mobileDetails.address;
|
|
state.order.serviceLocation.address2 = mobileDetails.address2;
|
|
state.order.serviceLocation.city = mobileDetails.city;
|
|
state.order.serviceLocation.isVehicleProtected = mobileDetails.isVehicleProtected;
|
|
},
|
|
updateServiceLocationTechNotes(state, techNotes) {
|
|
state.order.serviceLocation.techNotes = techNotes;
|
|
},
|
|
updateSchedule(state, scheduleInfo) {
|
|
if (scheduleInfo) {
|
|
state.order.schedule.date = scheduleInfo.date;
|
|
state.order.schedule.startTime = scheduleInfo.startTime;
|
|
state.order.schedule.endTime = scheduleInfo.endTime;
|
|
state.order.schedule.routeCode = scheduleInfo.routeCode;
|
|
state.order.schedule.jobMaxMinutes = scheduleInfo.jobMaxMinutes;
|
|
state.order.schedule.jobMinMinutes = scheduleInfo.jobMinMinutes;
|
|
}
|
|
},
|
|
updateCustomerDetails(state, customerDetails) {
|
|
if (customerDetails) {
|
|
state.order.customer.firstName = customerDetails.firstName;
|
|
state.order.customer.lastName = customerDetails.lastName;
|
|
state.order.customer.emailAddress = customerDetails.emailAddress;
|
|
state.order.customer.phoneNumber = customerDetails.phoneNumber;
|
|
state.order.customer.isSmsOptIn = customerDetails.isSmsOptIn;
|
|
}
|
|
},
|
|
updateInsuranceDetails(state, insuranceDetails) {
|
|
if (insuranceDetails) {
|
|
state.order.policy.policyNumber = insuranceDetails.policyNumber;
|
|
state.order.customer.address.streetAddress = insuranceDetails.streetAddress;
|
|
state.order.customer.address.streetAddress2 = insuranceDetails.streetAddress2;
|
|
state.order.customer.address.city = insuranceDetails.city;
|
|
state.order.customer.address.state = insuranceDetails.state;
|
|
state.order.customer.address.zipCode = insuranceDetails.zipCode;
|
|
state.order.payment.insuranceCoverage.claimNumber = insuranceDetails.claimNumber;
|
|
state.order.policy.phoneNumber = insuranceDetails.phoneNumber;
|
|
state.order.policy.phoneExtension = insuranceDetails.phoneExtension;
|
|
state.order.policy.morePolicyQuestions = insuranceDetails.morePolicyQuestions;
|
|
state.order.policy.dateOfBirth = insuranceDetails.dateOfBirth;
|
|
state.order.policy.lossTime = insuranceDetails.lossTime;
|
|
state.order.policy.lastName = insuranceDetails.lastName;
|
|
state.order.policy.lossLocation = insuranceDetails.lossLocation;
|
|
state.order.policy.subrogation = insuranceDetails.subrogation;
|
|
state.order.policy.currentDeductible = insuranceDetails.currentDeductible;
|
|
state.order.policy.originalDeductible = insuranceDetails.originalDeductible;
|
|
state.order.payment.insuranceCoverage.coverageStatus = coverageStatusValue(
|
|
insuranceDetails.coverageStatus
|
|
);
|
|
state.order.payment.insuranceCoverage.coverageSubStatus =
|
|
insuranceDetails.coverageSubStatus;
|
|
}
|
|
},
|
|
updateDamageDetails(state, damageDetails) {
|
|
if (damageDetails) {
|
|
state.order.damage.dateOfLoss = damageDetails.dateOfLoss;
|
|
state.order.damage.damageCause = damageDetails.damageCause;
|
|
}
|
|
},
|
|
|
|
// applicationUser MUTATIONS
|
|
updateSaveSessionPromise(state, saveSessionPromise) {
|
|
state.applicationUser.saveSessionPromise = saveSessionPromise;
|
|
},
|
|
updateSavedSessionId(state, savedSessionId) {
|
|
state.applicationUser.savedSessionId = savedSessionId;
|
|
},
|
|
updateCrmCustomerId(state, crmCustomerId) {
|
|
state.applicationUser.crmCustomerId = crmCustomerId;
|
|
},
|
|
updateLastPageVisited(state, lastPageVisited) {
|
|
state.applicationUser.lastPageVisited = lastPageVisited;
|
|
},
|
|
updateLoggingOption(state, loggingOption) {
|
|
state.applicationUser.loggingOption = loggingOption;
|
|
},
|
|
// EVENT BUS MUTATIONS
|
|
addEventToBus(state, event) {
|
|
state.applicationUser.eventBus.push(event);
|
|
},
|
|
removeEventFromBus(state, eventData) {
|
|
const matchedEvent = state.applicationUser.eventBus.find(
|
|
({ category, subCategory }) =>
|
|
category === eventData.category && subCategory === eventData.subCategory
|
|
);
|
|
const itemIndex = state.applicationUser.eventBus.indexOf(matchedEvent);
|
|
|
|
// If the item exists, remove it.
|
|
if (itemIndex > -1) {
|
|
state.applicationUser.eventBus.splice(itemIndex, 1);
|
|
}
|
|
},
|
|
//ExternalParameter MUTATIONS
|
|
updateIsExternalParameter(state, isExternalParameter) {
|
|
externalParameterState.isExternalParameter = isExternalParameter;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
updateExternalParameterYear(state, year) {
|
|
externalParameterState.vehicle.year = year;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
updateExternalParameterMake(state, make) {
|
|
externalParameterState.vehicle.make = make;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
updateExternalParameterModel(state, model) {
|
|
externalParameterState.vehicle.model = model;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
updateExternalParameterStyle(state, style) {
|
|
externalParameterState.vehicle.style = style;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
updateExternalParameterQsStash(state, qsStash) {
|
|
externalParameterState.qsStash = qsStash;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
updateExternalParameterIsRepair(state, isRepair) {
|
|
externalParameterState.vehicleDamage.isRepair = isRepair;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
updateExternalParameterNumberOfChips(state, numberOfChips) {
|
|
externalParameterState.vehicleDamage.numberOfChips = numberOfChips;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
updateExternalParameterDamageType(state, damageType) {
|
|
externalParameterState.vehicleDamage.damageType = damageType;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
updateExternalParameterZipCode(state, zipCode) {
|
|
externalParameterState.serviceZip.zipCode = zipCode;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
updateExternalParameterEmailAddress(state, emailAddress) {
|
|
externalParameterState.customer.emailAddress = emailAddress;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
updateExternalParameterIsInsurance(state, isInsurance) {
|
|
externalParameterState.quote.isInsurance = isInsurance;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
updateExternalParameterVinSelection(state, vinSelection) {
|
|
externalParameterState.estimate.vinSelection = vinSelection;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
updateExternalParameterServicePackage(state, servicePackage) {
|
|
externalParameterState.quote.servicePackage = servicePackage;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
updateExternalParameterPhoneNumber(state, phoneNumber) {
|
|
externalParameterState.customer.phoneNumber = phoneNumber;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
//RESET ExternalParameter MUTATIONS
|
|
resetExternalParameterVehicleState(state) {
|
|
externalParameterState.vehicle.year = null;
|
|
externalParameterState.vehicle.make = null;
|
|
externalParameterState.vehicle.model = null;
|
|
externalParameterState.vehicle.style = null;
|
|
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
resetExternalParameterDamageState(state) {
|
|
externalParameterState.vehicleDamage.isRepair = null;
|
|
externalParameterState.vehicleDamage.numberOfChips = null;
|
|
externalParameterState.vehicleDamage.damageType = null;
|
|
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
resetExternalParameterEstimateState(state) {
|
|
externalParameterState.estimate.vinSelection = null;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
resetExternalParameterServiceZipState(state) {
|
|
externalParameterState.serviceZip.zipCode = null;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
resetExternalParameterQuoteState(state) {
|
|
externalParameterState.quote.servicePackage = null;
|
|
externalParameterState.quote.isInsurance = null;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
resetIsExternalParameter(state) {
|
|
externalParameterState.isExternalParameter = externalParameterStatus.INACTIVE;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
resetExternalParameterCustomerState(state) {
|
|
externalParameterState.customer.emailAddress = null;
|
|
externalParameterState.customer.phoneNumber = null;
|
|
saveExternalParameterState(externalParameterState);
|
|
},
|
|
|
|
// RESET DEPENDENCY MUTATIONS
|
|
resetVehicleState(state) {
|
|
state.order.vehicle.year = null;
|
|
state.order.vehicle.make = null;
|
|
state.order.vehicle.model = null;
|
|
state.order.vehicle.style = null;
|
|
state.order.vehicle.carId = null;
|
|
state.order.vehicle.category = null;
|
|
state.order.vehicle.vin = null;
|
|
state.order.vehicle.imageUrl = null;
|
|
state.order.vehicle.imageVifNumber = null;
|
|
state.order.vehicle.imageColor = null;
|
|
},
|
|
resetDamageState(state) {
|
|
state.order.damage.isRepair = null;
|
|
state.order.damage.numberOfChips = null;
|
|
state.order.damage.glassToReplace = null;
|
|
},
|
|
resetRegistrationState(state) {
|
|
state.order.vehicle.registration.licensePlate = null;
|
|
},
|
|
resetGlassPartsState(state) {
|
|
state.order.lineItems.glassParts = null;
|
|
state.order.damage.partQuestionAnswers = null;
|
|
state.order.damage.moldingQuestionAnswers = null;
|
|
state.order.damage.capabilityQuestionAnswers = null;
|
|
state.applicationUser.pageData[routeData.PART_QUESTIONS.name] = null;
|
|
state.applicationUser.pageData[routeData.VEHICLE_PARTS.name] = null;
|
|
state.applicationUser.pageData[routeData.MOLDING_QUESTIONS.name] = null;
|
|
state.applicationUser.pageData[routeData.CAPABILITY_QUESTIONS.name] = null;
|
|
},
|
|
resetSchedule(state) {
|
|
state.order.schedule.date = null;
|
|
state.order.schedule.startTime = null;
|
|
state.order.schedule.endTime = null;
|
|
state.order.schedule.routeCode = null;
|
|
state.order.schedule.jobMaxMinutes = null;
|
|
state.order.schedule.jobMinMinutes = null;
|
|
|
|
//premium appointment fee used on schedule page also needs reset when schedule is reset
|
|
const supportingItems = state.order.lineItems.supportingItems;
|
|
const premiumAppointmentFeeIndex = supportingItems?.findIndex(
|
|
(item) => item.partType == PREMIUM_FEE_PART_TYPE
|
|
);
|
|
|
|
if (premiumAppointmentFeeIndex >= 0) {
|
|
supportingItems.splice(premiumAppointmentFeeIndex, 1);
|
|
state.order.lineItems.supportingItems = supportingItems;
|
|
}
|
|
},
|
|
resetState(state) {
|
|
Object.assign(state, getDefaultState());
|
|
},
|
|
// Bumps when submittedState sessionStorage is created, updated, or cleared so getters
|
|
// that read sessionStorage (coverageIsVerified, etc.) invalidate their Vuex cache.
|
|
incrementSubmittedStateRevision(state) {
|
|
state.submittedStateRevision = (state.submittedStateRevision ?? 0) + 1;
|
|
},
|
|
resetSaveSessionPromise(state) {
|
|
state.applicationUser.saveSessionPromise = null;
|
|
},
|
|
resetServiceLocationAppointmentType(state) {
|
|
state.order.serviceLocation.appointmentType = null;
|
|
},
|
|
resetServiceLocationProvider(state) {
|
|
state.order.serviceLocation.provider = {
|
|
providerNumber: null,
|
|
address: {
|
|
streetAddress: null,
|
|
city: null,
|
|
state: null,
|
|
zipCode: null,
|
|
zipCodeCtu: null,
|
|
},
|
|
};
|
|
},
|
|
resetServiceLocationMobileAddress(state) {
|
|
state.order.serviceLocation.address = null;
|
|
state.order.serviceLocation.address2 = null;
|
|
state.order.serviceLocation.city = null;
|
|
state.order.serviceLocation.state = null;
|
|
state.order.serviceLocation.isVehicleProtected = null;
|
|
},
|
|
resetPaymentMethodChoice(state) {
|
|
state.order.payment.isPia = null;
|
|
state.order.payment.piaType = null;
|
|
},
|
|
// Misc Mutations
|
|
updateStateWithOrderInformation(state, sessionInformation) {
|
|
state.order.referralNumber = sessionInformation.order.referralNumber;
|
|
state.order.referralSequenceNumber = sessionInformation.order.referralSequenceNumber;
|
|
state.order.referralDate = sessionInformation.order.referralDate;
|
|
state.order.referralCorrelationId = sessionInformation.order.referralCorrelationId;
|
|
state.order.eon = sessionInformation.order.eon;
|
|
state.order.customerPortalLoginToken = sessionInformation.order.CustomerPortalLoginToken;
|
|
state.order.isRecalAckOptIn = sessionInformation.order.isRecalAckOptIn;
|
|
state.order.workOrderId = sessionInformation.order.workOrderId
|
|
? sessionInformation.order.workOrderId
|
|
: null;
|
|
state.order.workOrderNumber = sessionInformation.order.workOrderNumber
|
|
? sessionInformation.order.workOrderNumber
|
|
: null;
|
|
state.order.lockToken = sessionInformation.order.lockToken
|
|
? sessionInformation.order.lockToken
|
|
: null;
|
|
|
|
if (state.order.vehicle.vin !== sessionInformation.order.vehicle?.vin) {
|
|
state.applicationUser.pageData[routeData.PART_QUESTIONS.name] = null;
|
|
state.applicationUser.pageData[routeData.VEHICLE_PARTS.name] = null;
|
|
state.applicationUser.pageData[routeData.MOLDING_QUESTIONS.name] = null;
|
|
state.applicationUser.pageData[routeData.CAPABILITY_QUESTIONS.name] = null;
|
|
}
|
|
|
|
state.order.vehicle = Object.assign(state.order.vehicle, {
|
|
year: sessionInformation.order.vehicle?.year,
|
|
make: sessionInformation.order.vehicle?.make,
|
|
model: sessionInformation.order.vehicle?.model,
|
|
style: sessionInformation.order.vehicle?.style,
|
|
vin: sessionInformation.order.vehicle?.vin,
|
|
carId: sessionInformation.order.vehicle?.carId,
|
|
category: sessionInformation.order.vehicle?.category,
|
|
imageUrl: sessionInformation.order.vehicle?.imageUrl,
|
|
imageVifNumber: sessionInformation.order.vehicle?.imageVifNumber,
|
|
imageColor: sessionInformation.order.vehicle?.imageVifColor,
|
|
vehicleSubType: sessionInformation.order.vehicle?.vehicleSubType,
|
|
vehicleSpecialClass: sessionInformation.order.vehicle?.vehicleSpecialClass,
|
|
isBigTruck: sessionInformation.order.vehicle?.isBigTruck,
|
|
canSafeliteService: sessionInformation.order.vehicle?.canSafeliteService,
|
|
vinRequired: sessionInformation.order.vehicle?.vinRequired,
|
|
});
|
|
|
|
state.order.damage.glassToReplace = sessionInformation.order.damage.glassToReplace;
|
|
state.order.damage.isRepair = sessionInformation.order.damage.isRepair;
|
|
state.order.damage.numberOfChips = sessionInformation.order.damage.numberOfChips;
|
|
state.order.damage.dateOfLoss = normalizeDotNetMinDate(
|
|
sessionInformation.order.damage?.dateOfLoss
|
|
);
|
|
state.order.damage.damageCause = sessionInformation.order.damage?.damageCause;
|
|
|
|
state.order.damage.partQuestionAnswers =
|
|
sessionInformation.order.damage.partQuestionAnswers;
|
|
state.order.damage.moldingQuestionAnswers =
|
|
sessionInformation.order.damage.moldingQuestionAnswers;
|
|
state.order.damage.capabilityQuestionAnswers =
|
|
sessionInformation.order.damage.capabilityQuestionAnswers;
|
|
|
|
state.order.damage.installOemGlass = sessionInformation.order.damage.installOemGlass;
|
|
|
|
state.order.lineItems.glassParts = sessionInformation.order.lineItems.glassParts;
|
|
state.order.lineItems.supportingItems = sessionInformation.order.lineItems.supportingItems;
|
|
state.order.lineItems.vaps = sessionInformation.order.lineItems.vaps ?? [];
|
|
state.order.lineItems.promos = sessionInformation.order.lineItems.promos;
|
|
state.order.lineItems.serverData = sessionInformation.order.lineItems.serverData;
|
|
|
|
state.order.payment.parentAccountNumber =
|
|
sessionInformation.order.payment.parentAccountNumber;
|
|
state.order.payment.billToAccountNumber =
|
|
sessionInformation.order.payment.billToAccountNumber;
|
|
state.order.payment.inactivePromos = sessionInformation.order.payment.inactivePromos;
|
|
state.order.payment.isClaimAndCoverage =
|
|
sessionInformation.order.payment.isClaimAndCoverage;
|
|
state.order.payment.canScheduleOnline = sessionInformation.order.payment.canScheduleOnline;
|
|
state.order.payment.accountName = sessionInformation.order.policy.insuranceCompanyName;
|
|
//Do not assign default service type once user make service type selection
|
|
if (state.order.serviceLocation.appointmentType == null) {
|
|
state.order.serviceLocation.address =
|
|
sessionInformation.order.serviceLocation.streetAddress;
|
|
state.order.serviceLocation.address2 =
|
|
sessionInformation.order.serviceLocation.streetAddress2;
|
|
state.order.serviceLocation.city = sessionInformation.order.serviceLocation.city;
|
|
state.order.serviceLocation.state = sessionInformation.order.serviceLocation.state;
|
|
state.order.serviceLocation.zipCode = sessionInformation.order.serviceLocation.zipCode;
|
|
state.order.serviceLocation.zipCodeCtu =
|
|
sessionInformation.order.serviceLocation.zipCodeCtu;
|
|
|
|
state.order.serviceLocation.appointmentType =
|
|
sessionInformation.order.serviceLocation.appointmentType;
|
|
state.order.serviceLocation.isVehicleProtected =
|
|
sessionInformation.order.serviceLocation.isVehicleProtected;
|
|
|
|
state.order.serviceLocation.provider.providerNumber =
|
|
sessionInformation.order.serviceLocation.provider?.providerNumber;
|
|
state.order.serviceLocation.provider.address.streetAddress =
|
|
sessionInformation.order.serviceLocation.provider?.address?.streetAddress;
|
|
state.order.serviceLocation.provider.address.city =
|
|
sessionInformation.order.serviceLocation.provider?.address?.city;
|
|
state.order.serviceLocation.provider.address.state =
|
|
sessionInformation.order.serviceLocation.provider?.address?.state;
|
|
state.order.serviceLocation.provider.address.zipCode =
|
|
sessionInformation.order.serviceLocation.provider?.address?.zipCode;
|
|
state.order.serviceLocation.provider.address.zipCodeCtu =
|
|
sessionInformation.order.serviceLocation.provider?.address?.zipCodeCtu;
|
|
state.order.serviceLocation.techNotes =
|
|
sessionInformation.order.serviceLocation.techNotes;
|
|
}
|
|
|
|
// if we're loading a session and we do not have a provider number yet, then set isInsurance to null so that
|
|
// a service package is not selected by default on the quote page.
|
|
if (
|
|
(sessionInformation.order.payment.isInsurance === null ||
|
|
sessionInformation.order.payment.isInsurance === undefined) &&
|
|
!sessionInformation.order.serviceLocation.provider?.providerNumber
|
|
) {
|
|
state.order.payment.isInsurance = null;
|
|
} else {
|
|
state.order.payment.isInsurance = sessionInformation.order.payment.isInsurance;
|
|
}
|
|
|
|
state.order.payment.insuranceCoverage.isVerified =
|
|
coverageStatusValue(sessionInformation?.order.insuranceCoverage.coverageStatus) ===
|
|
coverageStatus.VERIFIED
|
|
? true
|
|
: false;
|
|
state.order.payment.insuranceCoverage.coverageStatus = coverageStatusValue(
|
|
sessionInformation?.order.insuranceCoverage.coverageStatus
|
|
);
|
|
state.order.payment.insuranceCoverage.coverageSubStatus =
|
|
sessionInformation?.order.insuranceCoverage.coverageSubStatus;
|
|
state.order.payment.insuranceCoverage.coverageType = coverageTypeValue(
|
|
sessionInformation?.order.insuranceCoverage.coverageType
|
|
);
|
|
state.order.payment.insuranceCoverage.coverageVerificationType =
|
|
sessionInformation?.order.insuranceCoverage.coverageVerificationType;
|
|
|
|
state.order.customer.emailAddress = sessionInformation.order.customer.emailAddress;
|
|
state.order.customer.firstName = sessionInformation.order.customer.firstName;
|
|
state.order.customer.lastName = sessionInformation.order.customer.lastName;
|
|
state.order.customer.phoneNumber = sessionInformation.order.customer.homePhone;
|
|
state.order.customer.isSmsOptIn = sessionInformation.order.customer.isSmsOptIn;
|
|
|
|
if (sessionInformation.order.customer.address) {
|
|
state.order.customer.address = Object.assign(state.order.customer.address, {
|
|
streetAddress: sessionInformation.order.customer.address.streetAddress,
|
|
streetAddress2: sessionInformation.order.customer.address.streetAddress2,
|
|
city: sessionInformation.order.customer.address.city,
|
|
state: sessionInformation.order.customer.address.state,
|
|
zipCode: sessionInformation.order.customer.address.zipCode,
|
|
});
|
|
}
|
|
|
|
state.applicationUser.experiments = sessionInformation.applicationUser.experiments;
|
|
state.applicationUser.crmCustomerId = sessionInformation.applicationUser.crmCustomerId;
|
|
state.applicationUser.pageData = sessionInformation.applicationUser.pageData;
|
|
state.applicationUser.lastPage = sessionInformation.applicationUser.lastPage;
|
|
|
|
if (sessionInformation.applicationUser.savedSessionId) {
|
|
state.applicationUser.savedSessionId =
|
|
sessionInformation.applicationUser.savedSessionId;
|
|
}
|
|
//Do not assign default schedule details once user make schedule selection
|
|
if (state.order.schedule.date == null) {
|
|
state.order.schedule.date = sessionInformation.order.schedule?.date;
|
|
state.order.schedule.startTime = sessionInformation.order.schedule?.startTime;
|
|
state.order.schedule.endTime = sessionInformation.order.schedule?.endTime;
|
|
state.order.schedule.routeCode = sessionInformation.order.schedule?.routeCode;
|
|
state.order.schedule.jobMaxMinutes = sessionInformation.order.schedule?.jobMaxMinutes;
|
|
state.order.schedule.jobMinMinutes = sessionInformation.order.schedule?.jobMinMinutes;
|
|
}
|
|
state.order.policy.currentDeductible = sessionInformation.order.policy?.currentDeductible;
|
|
state.order.policy.originalDeductible = sessionInformation.order.policy?.originalDeductible;
|
|
state.order.policy.additionalAuthFlag = sessionInformation.order.policy?.additionalAuthFlag;
|
|
state.order.policy.isItac =
|
|
coverageTypeValue(sessionInformation?.order.insuranceCoverage.coverageType) ===
|
|
coverageType.ITAC
|
|
? true
|
|
: false;
|
|
state.order.policy.policyNumber = sessionInformation.order.policy?.policyNumber;
|
|
state.order.payment.insuranceCoverage.claimNumber =
|
|
sessionInformation.order.insuranceCoverage?.claimNumber;
|
|
state.order.policy.insuranceCompanyName =
|
|
sessionInformation.order.policy?.insuranceCompanyName;
|
|
|
|
state.order.policy.isNoComp =
|
|
coverageTypeValue(sessionInformation?.order.insuranceCoverage.coverageType) ===
|
|
coverageType.NOCOMP
|
|
? true
|
|
: false;
|
|
sessionInformation.order.policy?.noComprehensive;
|
|
},
|
|
updateExperiments(state, experiments) {
|
|
state.applicationUser.experiments = experiments;
|
|
},
|
|
updateTriggeredSiteEntry(state, wasSiteEntryTriggered) {
|
|
state.applicationUser.triggeredSiteEntry = wasSiteEntryTriggered;
|
|
},
|
|
updateAffiliateCookies(state, affiliateCookies) {
|
|
state.applicationUser.affiliateCookies = affiliateCookies;
|
|
},
|
|
updateHasTriggeredError(state, hasTriggeredError) {
|
|
state.applicationUser.hasAlreadyTriggeredError = hasTriggeredError;
|
|
},
|
|
updateIdempotencyKey(
|
|
state,
|
|
{ idempotencyKey, referralCorrelationId, totalInCents, expiryTime }
|
|
) {
|
|
state.idempotencyKeyFields.idempotencyKey = idempotencyKey;
|
|
state.idempotencyKeyFields.referralCorrelationId = referralCorrelationId;
|
|
state.idempotencyKeyFields.totalInCents = totalInCents;
|
|
state.idempotencyKeyFields.expiryTime = expiryTime;
|
|
},
|
|
};
|
|
|
|
// Export Getters
|
|
export const getters = {
|
|
vehicle: (state) => state.order.vehicle,
|
|
eventBusItem: (state) => (eventCategory, eventSubCategory) => {
|
|
const matchedEvent = state.applicationUser.eventBus.find(
|
|
({ category, subCategory }) =>
|
|
category === eventCategory && subCategory === eventSubCategory
|
|
);
|
|
|
|
return matchedEvent !== undefined ? matchedEvent.eventValue : undefined;
|
|
},
|
|
eventBus: (state) => state.applicationUser.eventBus,
|
|
damage: (state) => state.order.damage,
|
|
hasExactlyOneChip: (state) => {
|
|
return state.order.damage?.numberOfChips === 1;
|
|
},
|
|
hasAnyNonWindshieldGlassParts: (state) => {
|
|
const nonWindshieldItems = state.order.damage.glassToReplace?.filter(
|
|
(glassToReplace) => glassToReplace.glassLocation != "Windshield"
|
|
);
|
|
return !!nonWindshieldItems?.length;
|
|
},
|
|
coverageIsVerified: (state) => {
|
|
state.submittedStateRevision;
|
|
let order;
|
|
if (window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE) !== null) {
|
|
order = JSON.parse(
|
|
window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE)
|
|
).order;
|
|
} 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;
|
|
},
|
|
isDropOffAppointment: (state) => {
|
|
return state.order.serviceLocation.appointmentType === AppointmentTypeStrings.DROP_OFF;
|
|
},
|
|
isOvernightDropOffAppointment: (state) => {
|
|
return state.order.schedule.routeCode?.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF);
|
|
},
|
|
isRecalibrationOnOrder: (state) => {
|
|
return getHasRecalibrationPart(state);
|
|
},
|
|
isRecalibrationOnSubmittedState: (state) => {
|
|
state.submittedStateRevision;
|
|
if (window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE) !== null) {
|
|
return getHasRecalibrationPart({
|
|
order: JSON.parse(
|
|
window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE)
|
|
).order,
|
|
});
|
|
}
|
|
return false;
|
|
},
|
|
shouldHideRecalibration: (state) => {
|
|
state.submittedStateRevision;
|
|
if (window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE) !== null) {
|
|
state = JSON.parse(
|
|
window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE)
|
|
);
|
|
}
|
|
let order = state.order;
|
|
let applicationUser = state.applicationUser;
|
|
if (order.payment.isInsurance) {
|
|
return false;
|
|
}
|
|
|
|
return (
|
|
hasSettingEqualTo(
|
|
experimentSettings.RECAL_PRICE_REMOVE,
|
|
"true",
|
|
getExperimentSettingsFromExperimentList(applicationUser.experiments)
|
|
) && getters.isRecalibrationOnOrder(state)
|
|
);
|
|
},
|
|
areRearWipersOnOrder: (state) => {
|
|
return !!state.order.lineItems.vaps?.some(
|
|
(vap) => vap.partType.toUpperCase() === partTypeStrings.REAR_WIPER.toUpperCase()
|
|
);
|
|
},
|
|
scheduleDisplayText: (state) => {
|
|
const dateModel = convertDateStringToDate(state.order.schedule.date);
|
|
const readableDate = dateModel?.toLocaleDateString("en-us", {
|
|
weekday: "long",
|
|
month: "long",
|
|
day: "numeric",
|
|
year: "numeric",
|
|
});
|
|
|
|
const readableStartTime = militaryToTwelveHourTime(state.order.schedule.startTime);
|
|
const readableEndTime = militaryToTwelveHourTime(state.order.schedule.endTime);
|
|
|
|
const readableDuration = getDisplayTextForDurationLength(
|
|
state.order.schedule.jobMinMinutes,
|
|
state.order.schedule.jobMaxMinutes
|
|
);
|
|
|
|
return {
|
|
date: readableDate,
|
|
startTime: readableStartTime,
|
|
endTime: readableEndTime,
|
|
duration: readableDuration,
|
|
};
|
|
},
|
|
lineItems: (state) => state.order.lineItems,
|
|
pageData: (state) => (page) => {
|
|
return state.applicationUser.pageData[page];
|
|
},
|
|
bailoutCode: (state) => state.applicationUser.pageData.bailout?.bailoutCode,
|
|
applicationUser: (state) => state.applicationUser,
|
|
order: (state) => state.order,
|
|
payment: (state) => state.order.payment,
|
|
policy: (state) => state.order.policy,
|
|
experimentOrder: (state) => {
|
|
return {
|
|
funnelVehicleYear: state.order.vehicle.year,
|
|
funnelVehicleMake: state.order.vehicle.make,
|
|
funnelVehicleModel: state.order.vehicle.model,
|
|
funnelVehicleStyle: state.order.vehicle.style,
|
|
funnelIsRepair: state.order.damage.isRepair,
|
|
funnelNumberOfChips: state.order.damage.numberOfChips,
|
|
funnelCarId: state.order.vehicle.carId,
|
|
funnelServiceCity: state.order.serviceLocation.city,
|
|
funnelServiceState: state.order.serviceLocation.state,
|
|
funnelServiceZipCode: state.order.serviceLocation.zipCode,
|
|
funnelServiceZipCodeCtu: state.order.serviceLocation.zipCodeCtu,
|
|
funnelPolicyIsItac: state.order.policy.isItac ? "true" : "false",
|
|
funnelPolicyIsNoComp: state.order.policy.isNoComp ? "true" : "false",
|
|
funnelProviderNumber: state.order.serviceLocation.provider.providerNumber,
|
|
funnelParentAccountNumber: state.order.payment.parentAccountNumber,
|
|
funnelReferralType: state.order.payment.isInsurance ? "INSURANCE" : "CASH QUOTE",
|
|
funnelIsCoverageVerified: state.order.payment.insuranceCoverage.isVerified,
|
|
funnelHasRecalibrationPart: getHasRecalibrationPart(state),
|
|
funnelSelectedMultiGlass: state.order.damage.glassToReplace?.length > 1,
|
|
funnelSelectedWindshieldGlass: getNonFalseValuesOfPropertyInArrayOfObjects(
|
|
state.order.damage.glassToReplace,
|
|
"glassLocation"
|
|
).includes(damageLocationsSelected.WINDSHIELD),
|
|
funnelSelectedBackGlass: getNonFalseValuesOfPropertyInArrayOfObjects(
|
|
state.order.damage.glassToReplace,
|
|
"glassLocation"
|
|
).includes(damageLocationsSelected.REAR),
|
|
funnelSelectedDriverSideGlass: getNonFalseValuesOfPropertyInArrayOfObjects(
|
|
state.order.damage.glassToReplace,
|
|
"glassLocation"
|
|
).includes(damageLocationsSelected.DRIVER),
|
|
funnelSelectedPassengerSideGlass: getNonFalseValuesOfPropertyInArrayOfObjects(
|
|
state.order.damage.glassToReplace,
|
|
"glassLocation"
|
|
).includes(damageLocationsSelected.PASSENGER),
|
|
|
|
funnelOrderPartNumbers: [
|
|
...getNonFalseValuesOfPropertyInArrayOfObjects(
|
|
state.order.lineItems.glassParts,
|
|
"partNumber"
|
|
),
|
|
...getNonFalseValuesOfPropertyInArrayOfObjects(
|
|
state.order.lineItems.supportingItems,
|
|
"partNumber"
|
|
),
|
|
...getNonFalseValuesOfPropertyInArrayOfObjects(
|
|
state.order.lineItems.vaps,
|
|
"partNumber"
|
|
),
|
|
],
|
|
|
|
funnelOrderPartTypes: [
|
|
...getNonFalseValuesOfPropertyInArrayOfObjects(
|
|
state.order.lineItems.glassParts,
|
|
"recalibrationType"
|
|
),
|
|
],
|
|
};
|
|
},
|
|
experimentSettings: (state) =>
|
|
getExperimentSettingsFromExperimentList(state.applicationUser.experiments),
|
|
|
|
isVerifiedAndDeductibleZeroConfirmed: (state) => {
|
|
// used in CMS on /payment-method in Header Sub Text, for FunnelSubHeaderWidget on cart pages
|
|
if (
|
|
state.order.policy.currentDeductible === 0 &&
|
|
getters.coverageIsVerified(state) &&
|
|
!state.order.policy.isNoComp
|
|
) {
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
isItacOrNoComp: (state) => {
|
|
// used in CMS on /payment-method in Header Sub Text, for FunnelSubHeaderWidget on cart pages
|
|
if (state.order.policy.isNoComp || state.order.policy.isItac) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
},
|
|
requiresVerifiedRedirecting: (state) => {
|
|
return state.order?.referralNumber?.length === 6;
|
|
},
|
|
externalParameterState: (state) => externalParameterState,
|
|
externalParameterVehicle: (state) => externalParameterState?.vehicle,
|
|
externalParameterDamage: (state) => externalParameterState?.vehicleDamage,
|
|
externalParameterQuote: (state) => externalParameterState?.quote,
|
|
externalParameterServiceZip: (state) => externalParameterState?.serviceZip,
|
|
externalParameterEstimate: (state) => externalParameterState?.estimate,
|
|
externalParameterCustomer: (state) => externalParameterState?.customer,
|
|
isExternalParameter: (state) => externalParameterState?.isExternalParameter,
|
|
|
|
emailOrSms: (state) => {
|
|
const email =
|
|
externalParameterState.customer.emailAddress ?? state.order.customer.emailAddress;
|
|
const phone =
|
|
externalParameterState.customer.phoneNumber ?? state.order.customer.phoneNumber;
|
|
|
|
if (!phone && !email) {
|
|
return null;
|
|
}
|
|
|
|
if (phone && !email) {
|
|
return phone;
|
|
}
|
|
|
|
if (email && !phone) {
|
|
return email;
|
|
}
|
|
|
|
// if we're here, then we have both email and phone so get the value from pageData to reflect what they entered on the page.
|
|
// if they didn't enter anything on the page default to email
|
|
return (
|
|
state.applicationUser.pageData[routeData.SERVICE_ZIP.name]?.emailOrSmsValue ??
|
|
state.order.customer.emailAddress
|
|
);
|
|
},
|
|
|
|
isIdempotencyKeyValid: (state) => {
|
|
if (!state.idempotencyKeyFields?.idempotencyKey) {
|
|
return false;
|
|
}
|
|
|
|
const referralCorrelationId = state.order?.referralCorrelationId;
|
|
if (
|
|
!referralCorrelationId ||
|
|
referralCorrelationId !== state.idempotencyKeyFields?.referralCorrelationId
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
const total = getAmountDue(state.order?.lineItems);
|
|
const totalInCents = Math.round(total * 100);
|
|
if (totalInCents !== state.idempotencyKeyFields?.totalInCents) {
|
|
return false;
|
|
}
|
|
|
|
const currentTime = new Date();
|
|
const expiryTime = new Date(state.idempotencyKeyFields.expiryTime);
|
|
if (!expiryTime || expiryTime.getTime() < currentTime.getTime()) {
|
|
return false;
|
|
}
|
|
|
|
// If all checks pass, then the key is valid.
|
|
return true;
|
|
},
|
|
};
|
|
|
|
// Export Actions
|
|
export const actions = {
|
|
// Vehicle API Actions
|
|
getVehicleYears(context, { pageNameToLog }) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetVehicleYears.method,
|
|
endpoint: endpoints.GetVehicleYears.url,
|
|
payload: {},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
lookupVehicleByYmms(context, { payload: { year, make, model, style }, pageNameToLog }) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LookupVehicleByYmms.method,
|
|
endpoint: `${endpoints.LookupVehicleByYmms.url}/${year}/${make}/${model}/${style}`,
|
|
payload: {},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
lookupVehicleByVin(context, { payload: { vin }, pageNameToLog }) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LookupVehicleByVin.method,
|
|
endpoint: endpoints.LookupVehicleByVin.url,
|
|
payload: {
|
|
vin: vin, // EX "1J4GW58S4XC541166"
|
|
logEnabled: context.getters.applicationUser.loggingOption,
|
|
},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
lookupVinByPlate(context, { payload: { licensePlate, licenseState }, pageNameToLog }) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LookupVinByPlate.method,
|
|
endpoint: endpoints.LookupVinByPlate.url,
|
|
payload: {
|
|
licensePlate: licensePlate,
|
|
licenseState: licenseState,
|
|
logEnabled: context.getters.applicationUser.loggingOption,
|
|
},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
lookupVinByAddress(
|
|
context,
|
|
{
|
|
payload: { licenseLastName, licenseStreetAddress, licenseZip, licenseState },
|
|
pageNameToLog,
|
|
}
|
|
) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LookupVinByAddress.method,
|
|
endpoint: endpoints.LookupVinByAddress.url,
|
|
payload: {
|
|
licenseLastName: licenseLastName,
|
|
licenseStreetAddress: licenseStreetAddress,
|
|
licenseZip: licenseZip,
|
|
licenseState: licenseState,
|
|
},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
lookupVinByImage(context, { payload, pageNameToLog }) {
|
|
const image = payload;
|
|
|
|
return new Promise((resolve, reject) => {
|
|
let reader = new FileReader();
|
|
reader.onload = (e) => {
|
|
resolve(reader.result);
|
|
};
|
|
reader.readAsDataURL(image);
|
|
}).then((result) => {
|
|
const components = result.split(",");
|
|
const contentType = image.type;
|
|
const imageBase64 = components[1];
|
|
|
|
const data = {
|
|
imageData: imageBase64,
|
|
contentType: contentType,
|
|
fileName: image.name,
|
|
};
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LookupVinByImage.method,
|
|
endpoint: endpoints.LookupVinByImage.url,
|
|
payload: data,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
});
|
|
},
|
|
|
|
isVinByAddressPermissible(context, { payload: { zip }, pageNameToLog }) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.IsVinByAddressPermissible.method,
|
|
endpoint: `${endpoints.IsVinByAddressPermissible.url}?zipcode=${zip}`,
|
|
payload: {},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
getVehicleMakes(context, { payload: { year }, pageNameToLog }) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetVehicleMakes.method,
|
|
endpoint: `${endpoints.GetVehicleMakes.url}/${year}`,
|
|
payload: {},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
getVehicleModels(context, { payload: { year, make }, pageNameToLog }) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetVehicleModels.method,
|
|
endpoint: `${endpoints.GetVehicleModels.url}/${year}/${make}`,
|
|
payload: {},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
getVehicleStyles(context, { payload: { year, make, model }, pageNameToLog }) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetVehicleStyles.method,
|
|
endpoint: `${endpoints.GetVehicleStyles.url}/${year}/${make}/${model}`,
|
|
payload: {},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
getVehicle(context, { payload: { year, make, model, style }, pageNameToLog }) {
|
|
return globalMethods
|
|
.callHttpClient({
|
|
methods: endpoints.GetVehicle.method,
|
|
endpoint: `${endpoints.GetVehicle.url}/${year}/${make}/${model}/${style}`,
|
|
payload: {},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
})
|
|
.then((response) => {
|
|
return response;
|
|
});
|
|
},
|
|
|
|
getDamageOptions(context, { payload: { carId }, pageNameToLog }) {
|
|
return globalMethods.callHttpClient({
|
|
methods: endpoints.GetDamageOptions.method,
|
|
endpoint: `${endpoints.GetDamageOptions.url}/${carId}`,
|
|
payload: {},
|
|
additionalSuccessEventDataHandler: (response) =>
|
|
"QueryStringZip: " + getQuerystringParameter(queryStrings.ZIP_CODE),
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
validateZip(context, { payload: { zip }, pageNameToLog }) {
|
|
const damageType = context.getters.damage.isRepair ? "Repair" : "Replace";
|
|
return globalMethods.callHttpClient({
|
|
methods: endpoints.ValidateZip.method,
|
|
endpoint: `${endpoints.ValidateZip.url}/${zip}/${damageType}`,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
getClosestApplicableShops(context, { payload: { zip, carId }, pageNameToLog }) {
|
|
return globalMethods.callHttpClient({
|
|
methods: endpoints.ClosestApplicableShops.method,
|
|
endpoint: `${endpoints.ClosestApplicableShops.url}/${zip}/${carId}`,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
// Dependency Actions
|
|
resetVehicleStateAndDependencies(context) {
|
|
context.commit(storeMutations.RESET_VEHICLE_STATE);
|
|
|
|
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
|
},
|
|
|
|
resetDamageAndDependencies(context) {
|
|
context.commit(storeMutations.RESET_DAMAGE_STATE);
|
|
|
|
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
|
|
|
context.commit(storeMutations.UPDATE_VAPS, null);
|
|
},
|
|
|
|
resetRegistrationAndDependencies(context) {
|
|
context.commit(storeMutations.RESET_REGISTRATION_STATE);
|
|
|
|
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
|
},
|
|
|
|
resetPartsAndDependencies(context) {
|
|
context.commit(storeMutations.RESET_GLASS_PARTS_STATE);
|
|
context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null);
|
|
context.commit(storeMutations.UPDATE_VAPS, null);
|
|
|
|
context.dispatch(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES);
|
|
},
|
|
|
|
resetServiceLocationAndDependencies(context) {
|
|
context.commit(storeMutations.RESET_SERVICE_LOCATION_APPOINTMENT_TYPE);
|
|
context.commit(storeMutations.RESET_SERVICE_LOCATION_PROVIDER);
|
|
|
|
context.commit(storeMutations.RESET_SCHEDULE);
|
|
context.commit(storeMutations.RESET_PAYMENT_METHOD_CHOICE);
|
|
},
|
|
|
|
resetState(context) {
|
|
context.commit(storeMutations.RESET_STATE);
|
|
},
|
|
|
|
resetSaveSessionPromise(context) {
|
|
context.commit(storeMutations.RESET_SAVE_SESSION_PROMISE);
|
|
},
|
|
|
|
getPageData(context, { pageName }) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetPageData.method,
|
|
endpoint: endpoints.GetPageData.url(
|
|
applicationConfig.APPLICATION_ABBREVIATION,
|
|
pageName
|
|
),
|
|
payload: {},
|
|
logApiCall: true,
|
|
pageNameToLog: pageName,
|
|
});
|
|
},
|
|
|
|
// Analytics Actions
|
|
logExperimentExposureAndUpdateStore(
|
|
context,
|
|
{ payload: { userId, deviceId, sessionKey, pageName, experiment }, pageNameToLog }
|
|
) {
|
|
const experiments = deepClone(context.getters.applicationUser.experiments);
|
|
const experimentToMarkAsExposed = experiments.find((ex) => {
|
|
return (
|
|
ex.universeId == experiment.universeId &&
|
|
ex.testId == experiment.testId &&
|
|
ex.variationId == experiment.variationId &&
|
|
ex.assignmentId == experiment.assignmentId
|
|
);
|
|
});
|
|
if (experimentToMarkAsExposed) {
|
|
experimentToMarkAsExposed.isExposed = true;
|
|
}
|
|
|
|
context.commit(storeMutations.UPDATE_EXPERIMENTS, experiments);
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LogExperimentExposureIfAssigned.method,
|
|
endpoint: endpoints.LogExperimentExposureIfAssigned.url,
|
|
payload: {
|
|
experimentForLogging: {
|
|
userId: userId,
|
|
deviceId: deviceId,
|
|
experimentUniverseId: experiment.universeId,
|
|
experimentUniverseName: experiment.universeName,
|
|
experimentTestId: experiment.testId,
|
|
experimentTestName: experiment.testName,
|
|
experimentVariationId: experiment.variationId,
|
|
experimentVariationName: experiment.variationName,
|
|
enabled: experiment.isActive,
|
|
isExposed: experiment.isExposed,
|
|
userPartitionNumber: experiment.userPartitionNumber,
|
|
assignmentId: experiment.assignmentId,
|
|
sessionKey: sessionKey,
|
|
pageName: pageName,
|
|
},
|
|
},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
// Location API Actions
|
|
getAlertReasonsByCtu(context, { payload: { ctu }, pageNameToLog }) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetAlertReasons.method,
|
|
endpoint: `${endpoints.GetAlertReasons.url}/${ctu}`,
|
|
payload: {},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
// Misc Actions
|
|
updateStoreWithSaveSessionResponse(
|
|
context,
|
|
{
|
|
referralNumber,
|
|
referralSequenceNumber,
|
|
referralDate,
|
|
referralCorrelationId,
|
|
eon,
|
|
parentAccountNumber,
|
|
savedSessionId,
|
|
crmCustomerId,
|
|
workOrderNumber,
|
|
workOrderId,
|
|
customerPortalLoginToken,
|
|
lockToken,
|
|
settledTenderAmount,
|
|
billToAccountNumber,
|
|
}
|
|
) {
|
|
context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber);
|
|
context.commit(storeMutations.UPDATE_REFERRAL_SEQUENCE_NUMBER, referralSequenceNumber);
|
|
context.commit(storeMutations.UPDATE_REFERRAL_DATE, referralDate);
|
|
context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, referralCorrelationId);
|
|
context.commit(storeMutations.UPDATE_EON, eon);
|
|
context.commit(storeMutations.UPDATE_PARENT_ACCT_NUMBER, parentAccountNumber);
|
|
context.commit(storeMutations.UPDATE_SAVED_SESSION_ID, savedSessionId);
|
|
context.commit(storeMutations.UPDATE_CRM_CUSTOMER_ID, crmCustomerId);
|
|
context.commit(storeMutations.WORK_ORDER_NUMBER, workOrderNumber);
|
|
context.commit(storeMutations.WORK_ORDER_ID, workOrderId);
|
|
context.commit(storeMutations.LOCK_TOKEN, lockToken);
|
|
context.commit(storeMutations.Customer_Portal_Login_Token, customerPortalLoginToken);
|
|
context.commit(storeMutations.UPDATE_SETTLED_TENDER_AMOUNT, settledTenderAmount);
|
|
context.commit(storeMutations.UPDATE_BILL_TO_ACCT_NUMBER, billToAccountNumber);
|
|
},
|
|
|
|
logPageView(
|
|
context,
|
|
{
|
|
userId,
|
|
sessionKey,
|
|
pageName,
|
|
sessionId,
|
|
action,
|
|
event,
|
|
shouldUseSessionId,
|
|
experimentsForUser,
|
|
referralSequenceNumber,
|
|
parentAccountNumber,
|
|
}
|
|
) {
|
|
if (!pageName) {
|
|
return;
|
|
}
|
|
|
|
var payload = {
|
|
userId: userId,
|
|
sessionKey: sessionKey,
|
|
sessionId: sessionId,
|
|
pageName: pageName,
|
|
applicationName: applicationConfig.ANALYTICS_APPLICATION_NAME,
|
|
action: action,
|
|
event: event,
|
|
shouldUseSessionId: shouldUseSessionId,
|
|
experimentsForUser: experimentsForUser,
|
|
referralSequenceNumber: referralSequenceNumber,
|
|
parentAccountNumber:
|
|
parentAccountNumber ?? applicationConfig.CASH_PARENT_ACCOUNT_NUMBER,
|
|
};
|
|
|
|
return globalMethods
|
|
.callHttpClient({
|
|
method: endpoints.LogPageView.method,
|
|
endpoint: endpoints.LogPageView.url,
|
|
payload: payload,
|
|
logApiCall: false,
|
|
})
|
|
.then((response) => {
|
|
return response;
|
|
});
|
|
},
|
|
|
|
logCustomEvent(
|
|
context,
|
|
{
|
|
userId,
|
|
sessionKey,
|
|
pageName,
|
|
sessionId,
|
|
category,
|
|
action,
|
|
label,
|
|
value,
|
|
shouldUseSessionId,
|
|
experimentsForUser,
|
|
referralSequenceNumber,
|
|
parentAccountNumber,
|
|
}
|
|
) {
|
|
if (!pageName || !category) {
|
|
return;
|
|
}
|
|
|
|
var payload = {
|
|
userId: userId,
|
|
sessionKey: sessionKey,
|
|
sessionId: sessionId,
|
|
pageName: pageName,
|
|
applicationName: applicationConfig.ANALYTICS_APPLICATION_NAME,
|
|
category: category,
|
|
action: action,
|
|
label: label,
|
|
value: value,
|
|
shouldUseSessionId: shouldUseSessionId,
|
|
experimentsForUser: experimentsForUser,
|
|
referralSequenceNumber: referralSequenceNumber,
|
|
parentAccountNumber:
|
|
parentAccountNumber ?? applicationConfig.CASH_PARENT_ACCOUNT_NUMBER,
|
|
};
|
|
|
|
return globalMethods
|
|
.callHttpClient({
|
|
method: endpoints.LogCustomEvent.method,
|
|
endpoint: endpoints.LogCustomEvent.url,
|
|
payload: payload,
|
|
logApiCall: false,
|
|
})
|
|
.then((response) => {
|
|
return response;
|
|
});
|
|
},
|
|
initializeSession(context, { userId, deviceId, sessionId, userAgent, referrer }) {
|
|
var payload = {
|
|
applicationName: applicationConfig.ANALYTICS_APPLICATION_NAME,
|
|
userId: userId,
|
|
deviceId: deviceId,
|
|
sessionId: sessionId,
|
|
userAgent: userAgent,
|
|
operatorId: "WEB",
|
|
userName: "SafeliteConceptFunnel",
|
|
referrer: referrer,
|
|
clientData: window.location.search,
|
|
};
|
|
|
|
return globalMethods
|
|
.callHttpClient({
|
|
method: endpoints.InitializeSession.method,
|
|
endpoint: endpoints.InitializeSession.url,
|
|
payload: payload,
|
|
logApiCall: false,
|
|
})
|
|
.then((response) => {
|
|
return response;
|
|
});
|
|
},
|
|
|
|
logPartQuestions(
|
|
context,
|
|
{ eon, ctu, workOrderId, workOrderNumber, carId, glassLocation, partQuestions, userAgent }
|
|
) {
|
|
var payload = {
|
|
applicationName: applicationConfig.APPLICATION_NAME,
|
|
eon: eon,
|
|
ctu: ctu,
|
|
workOrderId: workOrderId,
|
|
workOrderNumber: workOrderNumber,
|
|
carId: carId,
|
|
glassLocation: glassLocation,
|
|
partQuestions: partQuestions,
|
|
userAgent: navigator.userAgent,
|
|
};
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LogPartQuestions.method,
|
|
endpoint: endpoints.LogPartQuestions.url,
|
|
payload: payload,
|
|
});
|
|
},
|
|
|
|
logFmgSessionData(
|
|
context,
|
|
{
|
|
currentPage,
|
|
sid,
|
|
deviceId,
|
|
fmgSessionId,
|
|
skey,
|
|
userId,
|
|
carId,
|
|
vehicleYear,
|
|
vehicleMake,
|
|
vehicleModel,
|
|
vehicleStyle,
|
|
hasVin,
|
|
cashOrInsuranceAccountType,
|
|
damageType,
|
|
productType,
|
|
eon,
|
|
referralNumber,
|
|
referralSequenceNumber,
|
|
referralDate,
|
|
workOrderNumber,
|
|
workOrderId,
|
|
isPia,
|
|
piaType,
|
|
parentAccountNumber,
|
|
billToAccountNumber,
|
|
settledTenderAmount,
|
|
recalRequired,
|
|
recalType,
|
|
serviceZipCode,
|
|
providerCtu,
|
|
appointmentDate,
|
|
serviceType,
|
|
promoCodes,
|
|
hasTechnicianNotes,
|
|
paymentMethod,
|
|
isTextingOptedIn,
|
|
isEarlyBird,
|
|
insuranceCo,
|
|
deductible,
|
|
isVerified,
|
|
coverageStatus,
|
|
coverageSubStatus,
|
|
isNoComp,
|
|
isItac,
|
|
isClaimAndCoverage,
|
|
vinRequired,
|
|
installOemGlass,
|
|
subTotalPrice,
|
|
totalPrice,
|
|
userAgent,
|
|
cashPriceSubTotal,
|
|
bailoutCode,
|
|
}
|
|
) {
|
|
var payload = {
|
|
currentPage: currentPage,
|
|
sid: sid,
|
|
deviceId: deviceId,
|
|
fmgSessionId: fmgSessionId,
|
|
skey: skey,
|
|
userId: userId,
|
|
carId: carId,
|
|
vehicleYear: vehicleYear,
|
|
vehicleMake: vehicleMake,
|
|
vehicleModel: vehicleModel,
|
|
vehicleStyle: vehicleStyle,
|
|
hasVin: hasVin,
|
|
cashOrInsuranceAccountType: cashOrInsuranceAccountType,
|
|
isVerified: isVerified,
|
|
coverageStatus: coverageStatus,
|
|
coverageSubStatus: coverageSubStatus,
|
|
damageType: damageType,
|
|
productType: productType,
|
|
eon: eon,
|
|
referralNumber: referralNumber,
|
|
referralSequenceNumber: referralSequenceNumber,
|
|
referralDate: referralDate,
|
|
workOrderNumber: workOrderNumber,
|
|
workOrderId: workOrderId,
|
|
isPia: isPia,
|
|
piaType: piaType,
|
|
parentAccountNumber: parentAccountNumber,
|
|
settledTenderAmount: settledTenderAmount,
|
|
recalRequired: recalRequired,
|
|
recalType: recalType,
|
|
serviceZipCode: serviceZipCode,
|
|
providerCtu: providerCtu,
|
|
appointmentDate: appointmentDate,
|
|
serviceType: serviceType,
|
|
promoCodes: promoCodes,
|
|
hasTechnicianNotes: hasTechnicianNotes,
|
|
paymentMethod: paymentMethod,
|
|
isTextingOptedIn: isTextingOptedIn,
|
|
isEarlyBird: isEarlyBird,
|
|
insuranceCo: insuranceCo,
|
|
deductible: deductible,
|
|
isNoComp: isNoComp,
|
|
isItac: isItac,
|
|
isClaimAndCoverage: isClaimAndCoverage,
|
|
vinRequired: vinRequired,
|
|
installOemGlass: installOemGlass,
|
|
subTotalPrice: subTotalPrice,
|
|
totalPrice: totalPrice,
|
|
userAgent: userAgent,
|
|
cashPriceSubTotal: cashPriceSubTotal,
|
|
billToAccountNumber: billToAccountNumber,
|
|
bailoutCode: bailoutCode,
|
|
};
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LogFmgSessionData.method,
|
|
endpoint: endpoints.LogFmgSessionData.url,
|
|
payload: payload,
|
|
logApiCall: false,
|
|
});
|
|
},
|
|
|
|
// Misc Actions
|
|
setReferralInformation(context, { referralNumber, referralDate, referralCorrelationId, eon }) {
|
|
context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber);
|
|
context.commit(storeMutations.UPDATE_REFERRAL_DATE, referralDate);
|
|
context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, referralCorrelationId);
|
|
context.commit(storeMutations.UPDATE_EON, eon);
|
|
},
|
|
|
|
GetExperimentsByUser(context, { userId }) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetExperimentsByUser.method,
|
|
endpoint: `${endpoints.GetExperimentsByUser.url}/${userId}`,
|
|
payload: {},
|
|
});
|
|
},
|
|
|
|
async runExperimentsForTrigger(
|
|
context,
|
|
{ payload: { deviceId, triggerEvent, triggerValue }, pageNameToLog }
|
|
) {
|
|
if (triggerEvent == experimentTriggers.SITE_ENTRY) {
|
|
context.commit(storeMutations.UPDATE_TRIGGERED_SITE_ENTRY, true);
|
|
}
|
|
|
|
var payload = {
|
|
applicationName: applicationConfig.APPLICATION_NAME,
|
|
deviceId: deviceId,
|
|
triggerEvent: triggerEvent,
|
|
triggerValue: triggerValue,
|
|
experimentOrder: context.getters.experimentOrder,
|
|
};
|
|
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.RunExperimentsForTrigger.method,
|
|
endpoint: endpoints.RunExperimentsForTrigger.url,
|
|
payload: payload,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
|
|
context.commit(storeMutations.UPDATE_EXPERIMENTS, response.data.experiments);
|
|
},
|
|
|
|
async forceExperiments(
|
|
context,
|
|
{ payload: { deviceId, queryStringExperiments }, pageNameToLog }
|
|
) {
|
|
var payload = {
|
|
applicationName: applicationConfig.APPLICATION_NAME,
|
|
deviceId: deviceId,
|
|
queryStringExperiments: queryStringExperiments,
|
|
};
|
|
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.ForceExperiments.method,
|
|
endpoint: endpoints.ForceExperiments.url,
|
|
payload: payload,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
getEvoxImage(context, { relativeUrl }) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetPageData.method,
|
|
endpoint: relativeUrl,
|
|
payload: {},
|
|
});
|
|
},
|
|
|
|
// PartsOrQuestions API Actions
|
|
async getPartsOrQuestions(context, { pageNameToLog }) {
|
|
const vehicle = context.getters.vehicle;
|
|
const damage = context.getters.damage;
|
|
const order = context.state.order;
|
|
|
|
const carId = vehicle.carId;
|
|
const glassArray = damage.glassToReplace;
|
|
const zipCode = order.serviceLocation.zipCode;
|
|
const vin = vehicle.vin;
|
|
const serviceType = damage.isRepair ? "Repair" : "Install";
|
|
const parentAccountNumber = context.getters.payment.parentAccountNumber;
|
|
const referralSeqNumber = order.referralSequenceNumber;
|
|
|
|
// create a new array to avoid mutating state
|
|
const glassArrayForPayload = convertGlassPieceNamingForApi(glassArray);
|
|
|
|
const partsOrQuestionsEndpoint = vehicle.vinRequired
|
|
? endpoints.GetPartsOrQuestionsV2
|
|
: endpoints.GetPartsOrQuestions;
|
|
|
|
const response = await globalMethods
|
|
.callHttpClient({
|
|
method: partsOrQuestionsEndpoint.method,
|
|
endpoint: partsOrQuestionsEndpoint.url,
|
|
payload: {
|
|
carId: carId,
|
|
glassPieces: glassArrayForPayload,
|
|
zip: zipCode,
|
|
vin: vin,
|
|
serviceType: serviceType,
|
|
referralSeqNumber: referralSeqNumber,
|
|
parentAccountNumber: parentAccountNumber,
|
|
},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
})
|
|
.catch((error) => {
|
|
if (error.status == 500) {
|
|
return { PartNotFound: true };
|
|
}
|
|
});
|
|
|
|
// Triggers bailout
|
|
if (response.PartNotFound) {
|
|
return response;
|
|
}
|
|
|
|
// Check if we only have MISC parts to trigger bailout
|
|
const miscPartsResponse = checkIfMiscParts(response.data.partsOrQuestions);
|
|
if (miscPartsResponse.PartNotFound) {
|
|
return miscPartsResponse;
|
|
}
|
|
|
|
// Flatten location and name properties
|
|
response.data.partsOrQuestions = convertGlassPieceNamingFromApi(
|
|
response.data.partsOrQuestions
|
|
);
|
|
|
|
return response;
|
|
},
|
|
|
|
// Parts API Actions
|
|
async getParts(context, { pageNameToLog }) {
|
|
const vehicle = context.getters.vehicle;
|
|
const damage = context.getters.damage;
|
|
const order = context.state.order;
|
|
const payment = context.getters.payment;
|
|
|
|
const carId = vehicle.carId;
|
|
const glassArray = damage.glassToReplace;
|
|
const resultsArray = damage.partQuestionAnswers;
|
|
const zipCode = order.serviceLocation.zipCode;
|
|
const vin = vehicle.vin;
|
|
const serviceType = order.serviceLocation?.appointmentType;
|
|
const referralSeqNumber = order.referralSequenceNumber;
|
|
const parentAccountNumber = payment.parentAccountNumber;
|
|
|
|
// create a new array to avoid mutating state
|
|
const glassArrayForPayload = convertGlassPieceNamingForApi(glassArray);
|
|
const resultsArrayForPayload = convertResultsForApi(resultsArray);
|
|
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.GetParts.method,
|
|
endpoint: endpoints.GetParts.url,
|
|
payload: {
|
|
carId: carId,
|
|
glassPieces: glassArrayForPayload,
|
|
answerResults: resultsArrayForPayload,
|
|
zip: zipCode,
|
|
vin: vin,
|
|
serviceType: serviceType,
|
|
referralSeqNumber: referralSeqNumber,
|
|
parentAccountNumber: parentAccountNumber,
|
|
},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
|
|
// Flatten location and name properties
|
|
response.data.glassPieceParts = convertGlassPieceNamingFromApi(
|
|
response.data.glassPieceParts
|
|
);
|
|
|
|
return response;
|
|
},
|
|
|
|
// Parts API Actions
|
|
async getOemAfterMarketParts(context, { pageNameToLog }) {
|
|
const vehicle = context.getters.vehicle;
|
|
const damage = context.getters.damage;
|
|
const order = context.state.order;
|
|
|
|
const carId = vehicle.carId;
|
|
const glassArray = damage.glassToReplace;
|
|
const resultsArray = damage.partQuestionAnswers;
|
|
const zipCode = order.serviceLocation.zipCode;
|
|
const vin = vehicle.vin;
|
|
const make = vehicle.make;
|
|
const serviceType = order.serviceLocation?.appointmentType;
|
|
const referralSeqNumber = order.referralSequenceNumber;
|
|
const parentAccountNumber = applicationConfig.CASH_PARENT_ACCOUNT_NUMBER;
|
|
const oemEndorsementFlag = order.damage.installOemGlass || false;
|
|
// create a new array to avoid mutating state
|
|
const glassArrayForPayload = convertGlassPieceNamingForApi(glassArray);
|
|
const resultsArrayForPayload = convertResultsForApi(resultsArray);
|
|
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.GetOemAfterMarketParts.method,
|
|
endpoint: endpoints.GetOemAfterMarketParts.url,
|
|
payload: {
|
|
carId: carId,
|
|
glassPieces: glassArrayForPayload,
|
|
answerResults: resultsArrayForPayload,
|
|
zip: zipCode,
|
|
vin: vin,
|
|
serviceType: serviceType,
|
|
referralSeqNumber: referralSeqNumber,
|
|
make: make,
|
|
parentAccountNumber: parentAccountNumber.toString(),
|
|
oemEndorsementFlag: oemEndorsementFlag,
|
|
},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
|
|
// Flatten location and name properties
|
|
if (response?.data?.glassPieceParts) {
|
|
response.data.glassPieceParts = convertGlassPieceNamingFromApi(
|
|
response.data.glassPieceParts
|
|
);
|
|
}
|
|
|
|
return response;
|
|
},
|
|
|
|
async getWipers(context, { payload, pageNameToLog }) {
|
|
const carId = payload.carId;
|
|
const accountNumber = payload.accountNumber;
|
|
|
|
const response = await globalMethods
|
|
.callHttpClient({
|
|
method: endpoints.GetWipers.method,
|
|
endpoint: `${endpoints.GetWipers.url}/${carId}/${accountNumber}`,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
})
|
|
.catch((error) => {
|
|
// The wiper service sometimes returns 500s on legitimate carId/zipCode combination - return empty array instead of breaking flow
|
|
return [];
|
|
});
|
|
|
|
syncLineItemIds(response.data, context.getters.order.lineItems.vaps);
|
|
return response;
|
|
},
|
|
|
|
async getRainRepel(context, { pageNameToLog }) {
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.GetRainRepel.method,
|
|
endpoint: endpoints.GetRainRepel.url,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
syncLineItemIds([response.data], context.getters.order.lineItems.vaps);
|
|
return response;
|
|
},
|
|
|
|
getMobileFeePart(
|
|
context,
|
|
{ payload: { serviceZipCode, serviceZipCodeCtu, mobileProviderNumber }, pageNameToLog }
|
|
) {
|
|
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 =
|
|
serviceZipCode ??
|
|
order.serviceLocation?.provider?.address?.zipCode ??
|
|
order.serviceLocation?.zipCode;
|
|
|
|
var providerNumber =
|
|
mobileProviderNumber ??
|
|
serviceZipCodeCtu ??
|
|
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}`;
|
|
|
|
const recalPartNumbers = getRecalPartNumbers(order.lineItems?.glassParts);
|
|
const carId = order.vehicle?.carId;
|
|
if (recalPartNumbers && recalPartNumbers.length > 0 && carId) {
|
|
let additionalQueryParams = ``;
|
|
for (let i = 0; i < recalPartNumbers.length; i++) {
|
|
additionalQueryParams += `&partNumbers[${i}]=${recalPartNumbers[i]}`;
|
|
}
|
|
additionalQueryParams += `&carId=${carId}`;
|
|
endPoint += additionalQueryParams;
|
|
}
|
|
|
|
if (coverageStatus) {
|
|
endPoint = `${endPoint}&coverageStatus=${coverageStatus}`;
|
|
}
|
|
|
|
if (coverageType) {
|
|
endPoint = `${endPoint}&coverageType=${coverageType}`;
|
|
}
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetMobileFeePart.method,
|
|
endpoint: endPoint,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
async getPricingByDayPart(context, { pageNameToLog }) {
|
|
return await globalMethods
|
|
.callHttpClient({
|
|
method: endpoints.GetPricingByDayPart.method,
|
|
endpoint: endpoints.GetPricingByDayPart.url,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
})
|
|
.then((response) => {
|
|
return response;
|
|
});
|
|
},
|
|
|
|
getServiceabilityDetails(context, { payload: { serviceZipCode }, pageNameToLog }) {
|
|
const flattenedLineItemsWithChildParts = getFlattenedArrayOfLineItemsWithChildParts(
|
|
context.getters.order.lineItems.glassParts
|
|
);
|
|
|
|
const lineItemsList = flattenedLineItemsWithChildParts
|
|
.map((item) => item.partNumber)
|
|
.join(",");
|
|
|
|
const vehicle = context.getters.vehicle;
|
|
const carId = vehicle.carId;
|
|
const damage = context.getters.damage;
|
|
|
|
const parentAccountNumber =
|
|
context.getters.order.payment.parentAccountNumber ??
|
|
applicationConfig.CASH_PARENT_ACCOUNT_NUMBER;
|
|
|
|
var endPoint = `${endpoints.GetServiceabilityDetails.url}?zip=${serviceZipCode}&carId=${carId}&parentAccountNumber=${parentAccountNumber}&isRepair=${damage.isRepair}`;
|
|
if (lineItemsList) {
|
|
endPoint += `&lineItems=${lineItemsList}`;
|
|
}
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetServiceabilityDetails.method,
|
|
endpoint: endPoint,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
getProviders(context, { payload: { serviceZipCode }, pageNameToLog }) {
|
|
const damageType = context.getters.damage.isRepair ? "Repair" : "Replace";
|
|
const accountNumber =
|
|
context.getters.order.payment.parentAccountNumber ??
|
|
applicationConfig.CASH_PARENT_ACCOUNT_NUMBER;
|
|
const carId = context.getters.order.vehicle.carId;
|
|
const partsWithRecal = getTopLevelPartsWithRecal(
|
|
context.getters.order.lineItems.glassParts
|
|
);
|
|
const windshieldPartWithRecal = partsWithRecal?.length > 0 ? partsWithRecal[0] : null;
|
|
|
|
const shopRadiusInMiles = 100;
|
|
|
|
let url = `${endpoints.GetProviders.url}/${serviceZipCode}/${damageType}/${shopRadiusInMiles}/${accountNumber}/true/${carId}`;
|
|
|
|
if (windshieldPartWithRecal) {
|
|
url += `/${windshieldPartWithRecal.partNumber}`;
|
|
}
|
|
//heavy truck vehicle
|
|
url += `/${context.getters.order.vehicle.isBigTruck}`;
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetProviders.method,
|
|
endpoint: url,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
getSupportingItems(context, { pageNameToLog }) {
|
|
const glassPartsArray = context.getters.lineItems.glassParts ?? [];
|
|
const carId = context.getters.vehicle.carId;
|
|
const isRepair = context.getters.damage.isRepair;
|
|
const numberOfChips = context.getters.damage.numberOfChips;
|
|
const apptType = context.getters.order?.serviceLocation?.appointmentType;
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetSupportingItems.method,
|
|
endpoint: endpoints.GetSupportingItems.url,
|
|
payload: {
|
|
carId: carId,
|
|
damageType: isRepair ? "Repair" : "Replace",
|
|
parentAccountNumber: applicationConfig.CASH_PARENT_ACCOUNT_NUMBER,
|
|
parts: glassPartsArray,
|
|
numberOfRepairChips: isRepair ? numberOfChips : 0,
|
|
providerNumber: context.getters.order.serviceLocation.zipCodeCtu,
|
|
facilityType:
|
|
apptType && apptType.trim() !== "" ? apptType : AppointmentTypeStrings.IN_SHOP,
|
|
},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
getCapabilityQuestions(context, { payload: { carId, partNumber }, pageNameToLog }) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetCapabilityQuestions.method,
|
|
endpoint: `${endpoints.GetCapabilityQuestions.url}/${carId}/${partNumber}`,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
async submitDonationPartToSV2(
|
|
context,
|
|
{ payload: { selectedItemNumber, submittedOrder }, pageNameToLog }
|
|
) {
|
|
const state = JSON.parse(
|
|
window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE)
|
|
);
|
|
const order = state.order;
|
|
const payload = {
|
|
selectedItemNumber: selectedItemNumber,
|
|
savedSessionId: state.applicationUser.savedSessionId,
|
|
paymentInfo: {
|
|
parentAccountNumber: order.payment.parentAccountNumber,
|
|
billToAccountNumber: order.payment.billToAccountNumber,
|
|
providerNumber: order.serviceLocation.provider.providerNumber,
|
|
carId: order.vehicle.carId,
|
|
make: order.vehicle.make,
|
|
model: order.vehicle.model,
|
|
year: order.vehicle.year,
|
|
eon: order.eon,
|
|
zipCode: order.serviceLocation.zipCode,
|
|
state: order.serviceLocation.state,
|
|
referralNumber: order.referralNumber,
|
|
referralDate: order.referralDate,
|
|
referralSequenceNumber: order.referralSequenceNumber,
|
|
serviceZipCode: order.serviceLocation.zipCode,
|
|
isReplacement: !order.damage.isRepair,
|
|
deductible: order.policy.currentDeductible,
|
|
coverageStatus: order.payment.insuranceCoverage.coverageStatus,
|
|
coverageSubStatus: order.payment.insuranceCoverage.coverageSubStatus,
|
|
serverData: order.lineItems.serverData,
|
|
},
|
|
};
|
|
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.AddDonationPart.method,
|
|
endpoint: endpoints.AddDonationPart.url,
|
|
payload: payload,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
return response.data;
|
|
},
|
|
|
|
getPartFromCapabilityQuestionAnswer(context, { payload, pageNameToLog }) {
|
|
const glassLocation = payload;
|
|
const pageData = context.getters.pageData(routeData.CAPABILITY_QUESTIONS.name);
|
|
|
|
const part = pageData.partsOrQuestions.find((x) => x.glassLocation === glassLocation)
|
|
.parts[0];
|
|
const capabilityQuestionAnswers = context.getters.damage.capabilityQuestionAnswers;
|
|
const capabilityQuestionAnswersForPart = capabilityQuestionAnswers.find(
|
|
(x) => x.glassLocation === glassLocation
|
|
);
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetPartFromCapabilityAnswer.method,
|
|
endpoint: endpoints.GetPartFromCapabilityAnswer.url,
|
|
payload: {
|
|
part,
|
|
capabilityAnswerResults: capabilityQuestionAnswersForPart,
|
|
},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
getShopTimeSlots(
|
|
context,
|
|
{ payload: { startDate, endDate, shopAppointmentType, providerNumber }, pageNameToLog }
|
|
) {
|
|
const order = context.state.order;
|
|
const vehicle = context.state.order.vehicle;
|
|
const payment = context.state.order.payment;
|
|
|
|
const lineItems = getFlattenedLineItemsWithGlassPartTag(order.lineItems);
|
|
|
|
const glassPieces = order.damage.glassToReplace
|
|
? convertGlassPieceToBackEndCompatibleFormat(order.damage.glassToReplace)
|
|
: [];
|
|
var payload = {
|
|
zipCode: order.serviceLocation.provider.zipCode,
|
|
providerNumber: providerNumber,
|
|
startDate: startDate,
|
|
endDate: endDate,
|
|
shopAppointmentType: shopAppointmentType,
|
|
applicationName: applicationConfig.APPLICATION_NAME,
|
|
parentAccountNumber: payment.parentAccountNumber,
|
|
carId: vehicle.carId,
|
|
lineItems: lineItems,
|
|
glassPieces: glassPieces,
|
|
eon: order.eon,
|
|
billToAccountNumber: context.getters.payment.billToAccountNumber,
|
|
coverage: {
|
|
status: payment.insuranceCoverage.coverageStatus,
|
|
deductible: order.policy.currentDeductible,
|
|
additionalAuthFlag: order.policy.additionalAuthFlag,
|
|
},
|
|
partSelection: {
|
|
hasAnsweredPartQuestions: !!order.damage.partQuestionAnswers?.length,
|
|
hasAnsweredMoldingQuestions: !!order.damage.moldingQuestionAnswers?.length,
|
|
hasAnsweredCapabilityQuestions: !!order.damage.capabilityQuestionAnswers?.length,
|
|
hasManuallySelectedParts:
|
|
!!context.state.applicationUser.pageData["vehicle-parts"]?.partsOrQuestions
|
|
.length,
|
|
},
|
|
vehicle: {
|
|
year: vehicle.year,
|
|
make: vehicle.make,
|
|
model: vehicle.model,
|
|
style: vehicle.style,
|
|
vin: vehicle.vin ?? "",
|
|
},
|
|
};
|
|
|
|
let hasCalled = timeSlotCallFlags.shop;
|
|
if (!hasCalled) {
|
|
timeSlotCallFlags.shop = true;
|
|
}
|
|
|
|
const options = {
|
|
method: endpoints.GetShopTimeSlots.method,
|
|
endpoint: endpoints.GetShopTimeSlots.url,
|
|
payload: payload,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
};
|
|
|
|
// Only set handler if this is the very first call in this session
|
|
if (!hasCalled) {
|
|
options.additionalSuccessEventDataHandler = (response) =>
|
|
getTimeSlotsAdditionalEventData(
|
|
response.data.provisionalTriggers,
|
|
order.serviceLocation.zipCode,
|
|
response.data.days?.[0]?.date,
|
|
shopAppointmentType
|
|
);
|
|
}
|
|
|
|
return globalMethods.callHttpClient(options);
|
|
},
|
|
|
|
getMobileTimeSlots(context, { payload: { startDate, endDate, zipCode }, pageNameToLog }) {
|
|
const order = context.state.order;
|
|
const vehicle = context.state.order.vehicle;
|
|
const payment = context.state.order.payment;
|
|
const lineItems = getFlattenedLineItemsWithGlassPartTag(order.lineItems);
|
|
const glassPieces = order.damage.glassToReplace
|
|
? convertGlassPieceToBackEndCompatibleFormat(order.damage.glassToReplace)
|
|
: [];
|
|
var payload = {
|
|
startDate: startDate,
|
|
endDate: endDate,
|
|
applicationName: applicationConfig.APPLICATION_NAME,
|
|
parentAccountNumber: payment.parentAccountNumber,
|
|
carId: vehicle.carId,
|
|
lineItems: lineItems,
|
|
glassPieces: glassPieces,
|
|
eon: order.eon,
|
|
billToAccountNumber: context.getters.payment.billToAccountNumber,
|
|
coverage: {
|
|
status: payment.insuranceCoverage.coverageStatus,
|
|
deductible: order.policy.currentDeductible,
|
|
additionalAuthFlag: order.policy.additionalAuthFlag,
|
|
},
|
|
partSelection: {
|
|
hasAnsweredPartQuestions: !!order.damage.partQuestionAnswers?.length,
|
|
hasAnsweredMoldingQuestions: !!order.damage.moldingQuestionAnswers?.length,
|
|
hasAnsweredCapabilityQuestions: !!order.damage.capabilityQuestionAnswers?.length,
|
|
hasManuallySelectedParts:
|
|
!!context.state.applicationUser.pageData["vehicle-parts"]?.partsOrQuestions
|
|
.length,
|
|
},
|
|
vehicle: {
|
|
year: vehicle.year,
|
|
make: vehicle.make,
|
|
model: vehicle.model,
|
|
style: vehicle.style,
|
|
vin: vehicle.vin ?? "",
|
|
},
|
|
zipCode: zipCode ?? order.serviceLocation.zipCode,
|
|
};
|
|
|
|
let hasCalled = timeSlotCallFlags.mobile;
|
|
if (!hasCalled) {
|
|
timeSlotCallFlags.mobile = true;
|
|
}
|
|
|
|
const options = {
|
|
method: endpoints.GetMobileTimeSlots.method,
|
|
endpoint: endpoints.GetMobileTimeSlots.url,
|
|
payload: payload,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
};
|
|
|
|
// Only set handler if this is the very first call in this session
|
|
if (!hasCalled) {
|
|
options.additionalSuccessEventDataHandler = (response) =>
|
|
getTimeSlotsAdditionalEventData(
|
|
response.data.provisionalTriggers,
|
|
order.serviceLocation.zipCode,
|
|
response.data.days?.[0]?.date
|
|
);
|
|
}
|
|
|
|
return globalMethods.callHttpClient(options);
|
|
},
|
|
|
|
getShopTimeSlotsV2(
|
|
context,
|
|
{ payload: { startDate, endDate, shopAppointmentType, providerNumbers }, pageNameToLog }
|
|
) {
|
|
const order = context.state.order;
|
|
const vehicle = context.state.order.vehicle;
|
|
const payment = context.state.order.payment;
|
|
|
|
const lineItems = getFlattenedLineItemsWithGlassPartTag(order.lineItems);
|
|
|
|
const glassPieces = order.damage.glassToReplace
|
|
? convertGlassPieceToBackEndCompatibleFormat(order.damage.glassToReplace)
|
|
: [];
|
|
var payload = {
|
|
providerNumbers: providerNumbers,
|
|
startDate: startDate,
|
|
endDate: endDate,
|
|
shopAppointmentType: shopAppointmentType,
|
|
applicationName: applicationConfig.APPLICATION_NAME,
|
|
parentAccountNumber: payment.parentAccountNumber,
|
|
carId: vehicle.carId,
|
|
lineItems: lineItems,
|
|
glassPieces: glassPieces,
|
|
eon: order.eon,
|
|
billToAccountNumber: context.getters.payment.billToAccountNumber,
|
|
coverage: {
|
|
status: payment.insuranceCoverage.coverageStatus,
|
|
deductible: order.policy.currentDeductible,
|
|
additionalAuthFlag: order.policy.additionalAuthFlag,
|
|
},
|
|
partSelection: {
|
|
hasAnsweredPartQuestions: !!order.damage.partQuestionAnswers?.length,
|
|
hasAnsweredMoldingQuestions: !!order.damage.moldingQuestionAnswers?.length,
|
|
hasAnsweredCapabilityQuestions: !!order.damage.capabilityQuestionAnswers?.length,
|
|
hasManuallySelectedParts:
|
|
!!context.state.applicationUser.pageData["vehicle-parts"]?.partsOrQuestions
|
|
.length,
|
|
},
|
|
vehicle: {
|
|
year: vehicle.year,
|
|
make: vehicle.make,
|
|
model: vehicle.model,
|
|
style: vehicle.style,
|
|
vin: vehicle.vin ?? "",
|
|
},
|
|
};
|
|
|
|
let hasCalled = timeSlotCallFlags.shopV2;
|
|
if (!hasCalled) {
|
|
timeSlotCallFlags.shopV2 = true;
|
|
}
|
|
|
|
const options = {
|
|
method: endpoints.GetShopTimeSlotsV2.method,
|
|
endpoint: endpoints.GetShopTimeSlotsV2.url,
|
|
payload: payload,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
};
|
|
|
|
// Only set handler if this is the very first call in this session
|
|
if (!hasCalled) {
|
|
options.additionalSuccessEventDataHandler = (response) => {
|
|
const firstProviderTimeSlots = response.data.providerTimeSlots?.[0];
|
|
return getTimeSlotsAdditionalEventData(
|
|
firstProviderTimeSlots?.provisionalTriggers,
|
|
order.serviceLocation.zipCode,
|
|
firstProviderTimeSlots?.days?.[0]?.date,
|
|
shopAppointmentType
|
|
);
|
|
};
|
|
}
|
|
|
|
return globalMethods.callHttpClient(options);
|
|
},
|
|
|
|
getMobileTimeSlotsV2(context, { payload: { startDate, endDate, zipCode }, pageNameToLog }) {
|
|
const order = context.state.order;
|
|
const vehicle = context.state.order.vehicle;
|
|
const payment = context.state.order.payment;
|
|
const lineItems = getFlattenedLineItemsWithGlassPartTag(order.lineItems);
|
|
const glassPieces = order.damage.glassToReplace
|
|
? convertGlassPieceToBackEndCompatibleFormat(order.damage.glassToReplace)
|
|
: [];
|
|
var payload = {
|
|
startDate: startDate,
|
|
endDate: endDate,
|
|
applicationName: applicationConfig.APPLICATION_NAME,
|
|
parentAccountNumber: payment.parentAccountNumber,
|
|
carId: vehicle.carId,
|
|
lineItems: lineItems,
|
|
glassPieces: glassPieces,
|
|
eon: order.eon,
|
|
billToAccountNumber: context.getters.payment.billToAccountNumber,
|
|
coverage: {
|
|
status: payment.insuranceCoverage.coverageStatus,
|
|
deductible: order.policy.currentDeductible,
|
|
additionalAuthFlag: order.policy.additionalAuthFlag,
|
|
},
|
|
partSelection: {
|
|
hasAnsweredPartQuestions: !!order.damage.partQuestionAnswers?.length,
|
|
hasAnsweredMoldingQuestions: !!order.damage.moldingQuestionAnswers?.length,
|
|
hasAnsweredCapabilityQuestions: !!order.damage.capabilityQuestionAnswers?.length,
|
|
hasManuallySelectedParts:
|
|
!!context.state.applicationUser.pageData["vehicle-parts"]?.partsOrQuestions
|
|
.length,
|
|
},
|
|
vehicle: {
|
|
year: vehicle.year,
|
|
make: vehicle.make,
|
|
model: vehicle.model,
|
|
style: vehicle.style,
|
|
vin: vehicle.vin ?? "",
|
|
},
|
|
zipCode: zipCode ?? order.serviceLocation.zipCode,
|
|
};
|
|
|
|
let hasCalled = timeSlotCallFlags.mobileV2;
|
|
if (!hasCalled) {
|
|
timeSlotCallFlags.mobileV2 = true;
|
|
}
|
|
|
|
const options = {
|
|
method: endpoints.GetMobileTimeSlotsV2.method,
|
|
endpoint: endpoints.GetMobileTimeSlotsV2.url,
|
|
payload: payload,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
};
|
|
|
|
// Only set handler if this is the very first call in this session
|
|
if (!hasCalled) {
|
|
options.additionalSuccessEventDataHandler = (response) =>
|
|
getTimeSlotsAdditionalEventData(
|
|
response.data.provisionalTriggers,
|
|
order.serviceLocation.zipCode,
|
|
response.data.days?.[0]?.date
|
|
);
|
|
}
|
|
|
|
return globalMethods.callHttpClient(options);
|
|
},
|
|
|
|
getMobilePremiumFee(context, { pageNameToLog }) {
|
|
const damageType = context.getters.damage.isRepair ? "Repair" : "Replace";
|
|
const paymentType = context.getters.order.payment.isInsurance ? "Insurance" : "Cash";
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetMobilePremiumFee.method,
|
|
endpoint: `${endpoints.GetMobilePremiumFee.url}/${paymentType}/${damageType}`,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
// Signing Service for Payment
|
|
getSignature() {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetSignature.method,
|
|
endpoint: endpoints.GetSignature.url,
|
|
});
|
|
},
|
|
|
|
// Session API Actions
|
|
saveQuote(context, { pageNameToLog, payload }) {
|
|
const vehicle = context.getters.vehicle;
|
|
const damage = context.getters.damage;
|
|
const order = context.state.order;
|
|
const applicationUser = context.getters.applicationUser;
|
|
const lineItems = context.state.order.lineItems;
|
|
const excludeRecalInquote = context.getters.shouldHideRecalibration;
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.SaveQuote.method,
|
|
endpoint: endpoints.SaveQuote.url,
|
|
payload: {
|
|
referralCorrelationId: order.referralCorrelationId,
|
|
referralNumber: order.referralNumber?.toString(),
|
|
referralSequenceNumber: order.referralSequenceNumber,
|
|
emailAddress: order.customer.emailAddress || undefined,
|
|
phoneNumber: order.customer.phoneNumber || undefined,
|
|
lastPage: pageNameToLog,
|
|
isRepair: damage.isRepair,
|
|
firstName: order.customer.firstName,
|
|
lastName: order.customer.lastName,
|
|
savedSessionId: applicationUser.savedSessionId,
|
|
serviceState: order.serviceLocation.state,
|
|
serviceZipCode: order.serviceLocation.zipCode,
|
|
parentAccountNumber: order.payment.parentAccountNumber,
|
|
excludeRecalInquote: excludeRecalInquote,
|
|
year: vehicle.year,
|
|
make: vehicle.make,
|
|
model: vehicle.model,
|
|
subType: vehicle.vehicleSubType,
|
|
specialClass: vehicle.vehicleSpecialClass,
|
|
isBigTruck: vehicle.isBigTruck,
|
|
isInsurance: order.payment.isInsurance ?? false,
|
|
isVerified: order.payment.insuranceCoverage.isVerified ?? false,
|
|
lineItems: {
|
|
glassParts: lineItems.glassParts,
|
|
supportingItems: lineItems.supportingItems,
|
|
vaps: lineItems.vaps,
|
|
serverData: lineItems.serverData,
|
|
promos: lineItems.promos,
|
|
},
|
|
coverageStatus: order.payment.insuranceCoverage.coverageStatus ?? "",
|
|
},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
},
|
|
|
|
saveSession(context, { pageNameToLog, payload }) {
|
|
const vehicle = context.getters.vehicle;
|
|
const damage = context.getters.damage;
|
|
const order = context.state.order;
|
|
const applicationUser = context.getters.applicationUser;
|
|
const lineItems = context.state.order.lineItems;
|
|
|
|
const submitAfterSave = payload?.submitAfterSave === "true";
|
|
const createUnscheduledStatusWorkOrderForPIA =
|
|
payload?.createUnscheduledStatusWorkOrderForPIA === "true";
|
|
|
|
// create a new array to avoid mutating state
|
|
const newGlassToReplace = convertGlassPieceNamingForApi(damage.glassToReplace);
|
|
//affiliate cookie save only when submitAfterSave
|
|
const affiliateCookies = submitAfterSave ? applicationUser.affiliateCookies : null;
|
|
|
|
let endPoint = endpoints.SaveSession.url;
|
|
if (createUnscheduledStatusWorkOrderForPIA) {
|
|
endPoint = endpoints.SubmitOrderForPia.url;
|
|
}
|
|
if (submitAfterSave) {
|
|
endPoint = endpoints.SubmitOrder.url;
|
|
}
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.SaveSession.method,
|
|
endpoint: endPoint,
|
|
payload: {
|
|
submitAfterSave: submitAfterSave,
|
|
userAgent: navigator.userAgent,
|
|
applicationUser: {
|
|
crmCustomerId: applicationUser.crmCustomerId,
|
|
experiments: applicationUser.experiments,
|
|
lastPage: applicationUser.lastPageVisited,
|
|
pageData: applicationUser.pageData,
|
|
savedSessionId: applicationUser.savedSessionId,
|
|
affiliateCookies: affiliateCookies,
|
|
},
|
|
order: {
|
|
vehicle: {
|
|
carId: vehicle.carId,
|
|
year: vehicle.year,
|
|
make: vehicle.make,
|
|
model: vehicle.model,
|
|
style: vehicle.style,
|
|
vin: vehicle.vin,
|
|
vehicleSubType: vehicle.vehicleSubType,
|
|
vehicleSpecialClass: vehicle.vehicleSpecialClass,
|
|
isBigTruck: vehicle.isBigTruck,
|
|
canSafeliteService: vehicle.canSafeliteService,
|
|
vinRequired: vehicle.vinRequired,
|
|
registration: {
|
|
firstName: vehicle.registration.firstName,
|
|
lastName: vehicle.registration.lastName,
|
|
streetAddress: vehicle.registration.address,
|
|
city: vehicle.registration.city,
|
|
state: vehicle.registration.state,
|
|
zipCode: vehicle.registration.zipCode,
|
|
licensePlateNumber: vehicle.registration.licensePlate,
|
|
},
|
|
},
|
|
customer: {
|
|
emailAddress: order.customer.emailAddress,
|
|
firstName: order.customer.firstName,
|
|
lastName: order.customer.lastName,
|
|
isSmsOptIn: order.customer.isSmsOptIn,
|
|
phoneNumber: order.customer.phoneNumber,
|
|
address: {
|
|
streetAddress: order.customer.address.streetAddress,
|
|
streetAddress2: order.customer.address.streetAddress2,
|
|
city: order.customer.address.city,
|
|
state: order.customer.address.state,
|
|
zipCode: order.customer.address.zipCode,
|
|
},
|
|
},
|
|
damage: {
|
|
numberOfChips: damage.numberOfChips,
|
|
glassToReplace: newGlassToReplace,
|
|
isRepair: damage.isRepair,
|
|
partQuestionAnswers: order.damage.partQuestionAnswers,
|
|
moldingQuestionAnswers: order.damage.moldingQuestionAnswers,
|
|
capabilityQuestionAnswers: order.damage.capabilityQuestionAnswers,
|
|
installOemGlass: order.damage.installOemGlass,
|
|
dateOfLoss: order.damage.dateOfLoss,
|
|
damageCause: order.damage.damageCause,
|
|
},
|
|
lineItems: {
|
|
glassParts: lineItems.glassParts,
|
|
supportingItems: lineItems.supportingItems,
|
|
vaps: lineItems.vaps,
|
|
serverData: lineItems.serverData,
|
|
promos: lineItems.promos,
|
|
},
|
|
payment: {
|
|
InsuranceCoverage: {
|
|
isVerified: order.payment.insuranceCoverage.isVerified ?? false,
|
|
coverageStatus:
|
|
order.payment.insuranceCoverage.coverageStatus?.toString(),
|
|
coverageVerificationType:
|
|
order.payment.insuranceCoverage.coverageVerificationType,
|
|
coverageSubStatus: order.payment.insuranceCoverage.coverageSubStatus,
|
|
claimNumber: order.payment.insuranceCoverage.claimNumber,
|
|
},
|
|
isInsurance: order.payment.isInsurance,
|
|
parentAccountNumber: order.payment.parentAccountNumber,
|
|
billToAccountNumber: order.payment.billToAccountNumber,
|
|
isClaimAndCoverage: order.payment.isClaimAndCoverage,
|
|
canScheduleOnline: order.payment.canScheduleOnline,
|
|
isManagedAccount: order.payment.isManagedAccount,
|
|
inactivePromos: order.payment.inactivePromos,
|
|
isCreditCard:
|
|
order.payment.piaType == paymentMethods.CREDIT_CARD ? true : false,
|
|
isPaypal: order.payment.piaType == paymentMethods.PAYPAL ? true : false,
|
|
isAfterPay: order.payment.piaType == paymentMethods.AFTERPAY ? true : false,
|
|
isApplePay:
|
|
order.payment.piaType == paymentMethods.APPLE_PAY ? true : false,
|
|
paypalToken: order.payment.paypalToken,
|
|
nextGenSettledAmount: order.payment.nextGenSettledAmount,
|
|
ccToken: {
|
|
subscriptionId: order.payment.ccToken.subscriptionId,
|
|
expMonth: order.payment.ccToken.expMonth,
|
|
expYear: order.payment.ccToken.expYear,
|
|
cardType: order.payment.ccToken.cardType,
|
|
billToPostalCode: order.payment.ccToken.billToPostalCode,
|
|
billToFirstName: order.payment.ccToken.billToFirstName,
|
|
billToLastName: order.payment.ccToken.billToLastName,
|
|
referenceNumber: order.payment.ccToken.referenceNumber,
|
|
authCode: order.payment.ccToken.authCode,
|
|
transactionId: order.payment.ccToken.transactionId,
|
|
transReferenceNumber: order.payment.ccToken.transReferenceNumber,
|
|
lastFour: order.payment.ccToken.lastFour,
|
|
},
|
|
},
|
|
policy: {
|
|
isItac: order.policy?.isItac,
|
|
isNoComp: order.policy?.isNoComp,
|
|
currentDeductible: order.policy?.currentDeductible,
|
|
originalDeductible: order.policy?.originalDeductible,
|
|
policyNumber: order.policy?.policyNumber,
|
|
},
|
|
serviceLocation: {
|
|
streetAddress: order.serviceLocation.address,
|
|
streetAddress2: order.serviceLocation.address2,
|
|
city: order.serviceLocation.city,
|
|
state: order.serviceLocation.state,
|
|
zipCode: order.serviceLocation.zipCode,
|
|
zipCodeCtu: order.serviceLocation.zipCodeCtu,
|
|
appointmentType: order.serviceLocation.appointmentType,
|
|
isVehicleProtected: order.serviceLocation.isVehicleProtected,
|
|
provider: {
|
|
providerNumber: order.serviceLocation.provider?.providerNumber,
|
|
address: {
|
|
streetAddress:
|
|
order.serviceLocation.provider?.address?.streetAddress,
|
|
city: order.serviceLocation.provider?.address?.city,
|
|
state: order.serviceLocation.provider?.address?.state,
|
|
zipCode: order.serviceLocation.provider?.address?.zipCode,
|
|
zipCodeCtu: order.serviceLocation.provider?.address?.zipCodeCtu,
|
|
},
|
|
},
|
|
techNotes: order.serviceLocation.techNotes,
|
|
},
|
|
schedule: {
|
|
date: order.schedule?.date,
|
|
startTime: order.schedule?.startTime,
|
|
endTime: order.schedule?.endTime,
|
|
routeCode: order.schedule?.routeCode,
|
|
jobMaxMinutes: order.schedule?.jobMaxMinutes,
|
|
jobMinMinutes: order.schedule?.jobMinMinutes,
|
|
},
|
|
referralCorrelationId: order.referralCorrelationId,
|
|
referralDate: order.referralDate,
|
|
referralNumber: order.referralNumber?.toString(),
|
|
referralSequenceNumber: order.referralSequenceNumber,
|
|
eon: order.eon,
|
|
createUnscheduledStatusWorkOrderForPIA: createUnscheduledStatusWorkOrderForPIA,
|
|
lockToken: order.lockToken,
|
|
isRecalAckOptIn: order.isRecalAckOptIn,
|
|
isMSRFeeApplicable: order.isMSRFeeApplicable,
|
|
isMSRFeeCoveredByInsurance: order.isMSRFeeCoveredByInsurance,
|
|
cashPriceSubTotal: order.cashPriceSubTotal,
|
|
},
|
|
},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
additionalSuccessEventDataHandler: (response) =>
|
|
"Email provided: " + (order.customer.emailAddress ? "true" : "false"),
|
|
});
|
|
},
|
|
|
|
loadSession(
|
|
context,
|
|
{
|
|
payload: {
|
|
savedSessionId,
|
|
referralNumber,
|
|
referralDate,
|
|
parentAccountNumber,
|
|
referralCorrelationId,
|
|
isConceptInsurance,
|
|
},
|
|
pageNameToLog,
|
|
}
|
|
) {
|
|
const order = context.state.order;
|
|
|
|
var dtParts = referralDate.split("-");
|
|
const year = dtParts[0];
|
|
const month = dtParts[1];
|
|
const day = dtParts[2].substring(0, 2);
|
|
|
|
const loadDate = `${year}-${month}-${day}`;
|
|
|
|
return globalMethods
|
|
.callHttpClient({
|
|
method: endpoints.LoadSession.method,
|
|
endpoint: endpoints.LoadSession.url,
|
|
payload: {
|
|
savedSessionId: savedSessionId?.toString(),
|
|
referralNumber: referralNumber?.toString(),
|
|
referralDate: loadDate,
|
|
parentAccountNumber: parentAccountNumber?.toString(),
|
|
referralCorrelationId: referralCorrelationId,
|
|
},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
})
|
|
.then(
|
|
async (response) => {
|
|
// Flatten location and name properties
|
|
response.data.order.damage?.glassToReplace?.map((glass) => {
|
|
glass.glassLocation = glass.location;
|
|
glass.glassName = glass.name;
|
|
delete glass.location;
|
|
delete glass.name;
|
|
return glass;
|
|
});
|
|
|
|
// clear the state if the existing EON does not equal what is returned from loadSession
|
|
if (
|
|
context.state.order.eon &&
|
|
context.state.order.eon != response.data.order.eon
|
|
) {
|
|
context.commit(storeMutations.RESET_STATE);
|
|
}
|
|
|
|
context.commit(
|
|
storeMutations.UPDATE_STATE_WITH_ORDER_INFORMATION,
|
|
response.data
|
|
);
|
|
|
|
await resetScheduleIfUnavailable(context, context.state.order, pageNameToLog);
|
|
return response;
|
|
},
|
|
(error) => {
|
|
deleteFunnelCookie();
|
|
context.commit(storeMutations.RESET_STATE);
|
|
}
|
|
);
|
|
},
|
|
|
|
saveCCToken(context, ccToken) {
|
|
context.commit(storeMutations.UPDATE_CCTOKEN, ccToken);
|
|
},
|
|
|
|
saveNextGenSettledAmount(context, nextGenSettledAmount) {
|
|
context.commit(storeMutations.UPDATE_NEXTGEN_SETTLED_AMOUNT, nextGenSettledAmount);
|
|
},
|
|
|
|
savePaypalToken(context, ppToken) {
|
|
context.commit(storeMutations.UPDATE_PAYPAL_TOKEN, ppToken);
|
|
},
|
|
|
|
// Business domain actions
|
|
|
|
// Vehicle
|
|
saveVehicle(
|
|
context,
|
|
{
|
|
year,
|
|
make,
|
|
model,
|
|
style,
|
|
vehicleSubType,
|
|
vehicleSpecialClass,
|
|
isBigTruck,
|
|
carId,
|
|
category,
|
|
canSafeliteService,
|
|
imageUrl,
|
|
imageVifNumber,
|
|
imageVifColor,
|
|
skipVINLookup,
|
|
skipPartQuestions,
|
|
vinRequired,
|
|
}
|
|
) {
|
|
if (
|
|
context.state.order.vehicle.year != year ||
|
|
context.state.order.vehicle.make != make ||
|
|
context.state.order.vehicle.model != model ||
|
|
context.state.order.vehicle.style != style
|
|
) {
|
|
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
|
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
|
|
|
context.commit(storeMutations.UPDATE_VEHICLE_VIN, null);
|
|
context.commit(storeMutations.UPDATE_YEAR, year);
|
|
context.commit(storeMutations.UPDATE_MAKE, make);
|
|
context.commit(storeMutations.UPDATE_MODEL, model);
|
|
context.commit(storeMutations.UPDATE_STYLE, style);
|
|
context.commit(storeMutations.UPDATE_VEHICLE_SUBTYPE, vehicleSubType);
|
|
context.commit(storeMutations.UPDATE_VEHICLE_SPECIAL_CLASS, vehicleSpecialClass);
|
|
context.commit(storeMutations.UPDATE_IS_BIGTRUCK, isBigTruck);
|
|
context.commit(storeMutations.UPDATE_CAR_ID, carId);
|
|
context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, category);
|
|
context.commit(storeMutations.UPDATE_VEHICLE_CAN_SAFELITE_SERVICE, canSafeliteService);
|
|
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, imageUrl);
|
|
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, imageVifNumber);
|
|
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, imageVifColor);
|
|
context.commit(storeMutations.UPDATE_SKIP_VIN_LOOKUP, skipVINLookup);
|
|
context.commit(storeMutations.UPDATE_SKIP_PART_QUESTIONS, skipPartQuestions);
|
|
context.commit(storeMutations.UPDATE_VIN_REQUIRED, vinRequired);
|
|
}
|
|
},
|
|
|
|
saveVehicleDamage(
|
|
context,
|
|
{ isWindshieldRepair, selectedGlassToReplace, selectedWindshieldChipCount }
|
|
) {
|
|
const selectedGlassPassedInSorted = selectedGlassToReplace.slice().sort();
|
|
const isGlassToReplaceTheSame =
|
|
context.state.order.damage.glassToReplace?.length === selectedGlassToReplace.length &&
|
|
context.state.order.damage.glassToReplace
|
|
.slice()
|
|
.sort()
|
|
.every(
|
|
(obj, index) =>
|
|
obj.glassLocation === selectedGlassPassedInSorted[index].glassLocation &&
|
|
obj.glassName === selectedGlassPassedInSorted[index].glassName
|
|
);
|
|
const isWindshieldRepairTheSame =
|
|
isWindshieldRepair === context.state.order.damage.isRepair;
|
|
|
|
const isChipCountTheSame =
|
|
selectedWindshieldChipCount === context.state.order.damage.numberOfChips;
|
|
|
|
const isDamageChanging =
|
|
!isGlassToReplaceTheSame ||
|
|
!isWindshieldRepairTheSame ||
|
|
(isWindshieldRepair && !isChipCountTheSame);
|
|
|
|
if (isDamageChanging) {
|
|
//Reset dependent state when changing
|
|
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
|
|
|
// Save new values
|
|
context.commit(storeMutations.UPDATE_IS_REPAIR, isWindshieldRepair);
|
|
context.commit(
|
|
storeMutations.UPDATE_NUMBER_OF_CHIPS,
|
|
isWindshieldRepair ? parseInt(selectedWindshieldChipCount) : null
|
|
);
|
|
context.commit(storeMutations.UPDATE_GLASS_TO_REPLACE, selectedGlassToReplace);
|
|
}
|
|
},
|
|
|
|
// Vin lookup
|
|
saveVinLookup(context, { isSelectedGlassAvailableForVehicle, vehicleInfo, registrationInfo }) {
|
|
//Reset dependent state when changing
|
|
if (vehicleInfo.vin !== context.state.order.vehicle.vin) {
|
|
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
|
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
|
|
|
if (!isSelectedGlassAvailableForVehicle) {
|
|
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
|
}
|
|
|
|
//Save new values
|
|
context.commit(storeMutations.UPDATE_VEHICLE, vehicleInfo);
|
|
context.commit(storeMutations.UPDATE_REGISTRATION, registrationInfo);
|
|
}
|
|
},
|
|
|
|
saveRegistrationLicensePlateLookup(
|
|
context,
|
|
{ isSelectedGlassAvailableForVehicle, vehicleInfo, registrationInfo }
|
|
) {
|
|
//Reset dependent state when changing
|
|
if (
|
|
registrationInfo?.licensePlate !==
|
|
context.state.order.vehicle.registration?.licensePlate
|
|
) {
|
|
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
|
|
|
if (!isSelectedGlassAvailableForVehicle) {
|
|
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
|
}
|
|
|
|
context.commit(storeMutations.UPDATE_VEHICLE, vehicleInfo);
|
|
|
|
if (registrationInfo) {
|
|
context.commit(storeMutations.UPDATE_REGISTRATION, registrationInfo);
|
|
|
|
// only update name information if there isn't a value in state already
|
|
if (!context.getters.order.customer.firstName) {
|
|
context.commit(storeMutations.UPDATE_CUSTOMER_DETAILS, {
|
|
firstName: registrationInfo.firstName,
|
|
lastName: registrationInfo.lastName,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
saveRegistrationAddressLookup(
|
|
context,
|
|
{ isSelectedGlassAvailableForVehicle, vehicleInfo, customerInfo }
|
|
) {
|
|
//Reset dependent state when changing
|
|
if (vehicleInfo.vin !== context.state.order.vehicle.vin) {
|
|
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
|
|
|
if (!isSelectedGlassAvailableForVehicle) {
|
|
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
|
}
|
|
}
|
|
|
|
context.commit(storeMutations.UPDATE_VEHICLE, vehicleInfo);
|
|
|
|
// only update name information if there isn't a value in state already
|
|
if (!context.getters.order.customer.firstName && customerInfo) {
|
|
context.commit(storeMutations.UPDATE_CUSTOMER_DETAILS, {
|
|
firstName: customerInfo.firstName,
|
|
lastName: customerInfo.lastName,
|
|
});
|
|
}
|
|
},
|
|
|
|
savePartQuestionAnswers(context, partQuestionAnswersArray) {
|
|
// if part question answers have changed, reset subsequent question answers
|
|
const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(
|
|
context.getters.damage.partQuestionAnswers,
|
|
"result"
|
|
);
|
|
const sortedPartQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(
|
|
partQuestionAnswersArray,
|
|
"result"
|
|
);
|
|
const havePartQuestionAnswersChanged =
|
|
sortedPreviousResultsArray?.length !== sortedPartQuestionAnswersArray.length ||
|
|
!sortedPreviousResultsArray?.every(
|
|
(x, i) => x.result === sortedPartQuestionAnswersArray[i].result
|
|
);
|
|
|
|
if (havePartQuestionAnswersChanged) {
|
|
context.dispatch(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES);
|
|
|
|
context.commit(storeMutations.UPDATE_GLASS_PARTS, null);
|
|
context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null);
|
|
context.commit(storeMutations.UPDATE_MOLDING_QUESTION_ANSWERS, null);
|
|
context.commit(storeMutations.UPDATE_CAPABILITY_QUESTION_ANSWERS, null);
|
|
context.commit(storeMutations.UPDATE_PAGE_DATA, {
|
|
page: routeData.VEHICLE_PARTS.name,
|
|
data: null,
|
|
});
|
|
context.commit(storeMutations.UPDATE_PAGE_DATA, {
|
|
page: routeData.MOLDING_QUESTIONS.name,
|
|
data: null,
|
|
});
|
|
context.commit(storeMutations.UPDATE_PAGE_DATA, {
|
|
page: routeData.CAPABILITY_QUESTIONS.name,
|
|
data: null,
|
|
});
|
|
}
|
|
|
|
//Save new values
|
|
context.commit(storeMutations.UPDATE_PART_QUESTION_ANSWERS, partQuestionAnswersArray);
|
|
},
|
|
|
|
resetMoldingAndCapabilityQuestionAnswersIfNeeded(context, matchedParts) {
|
|
const partsOrQuestionsDataToCompareWith =
|
|
context.getters.pageData(routeData.MOLDING_QUESTIONS.name)?.partsOrQuestions ??
|
|
context.getters.pageData(routeData.CAPABILITY_QUESTIONS.name)?.partsOrQuestions ??
|
|
[];
|
|
|
|
function getAllPartNumbers(partsOrQuestions) {
|
|
return partsOrQuestions[0]?.parts
|
|
? [...partsOrQuestions]
|
|
.map((glass) => glass.parts)
|
|
.flat()
|
|
.map((part) => part.partNumber)
|
|
.filter((partNumber) => !partNumber.toUpperCase().includes("FEE"))
|
|
.sort()
|
|
.join(",")
|
|
: [];
|
|
}
|
|
|
|
const previouslySelectedPartNumbers = getAllPartNumbers(partsOrQuestionsDataToCompareWith);
|
|
const currentlySelectedPartNumbers = getAllPartNumbers(matchedParts);
|
|
|
|
const haveSelectedVehiclePartsChanged =
|
|
previouslySelectedPartNumbers !== currentlySelectedPartNumbers;
|
|
|
|
if (haveSelectedVehiclePartsChanged) {
|
|
context.dispatch(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES);
|
|
|
|
context.commit(storeMutations.UPDATE_GLASS_PARTS, null);
|
|
context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null);
|
|
context.commit(storeMutations.UPDATE_MOLDING_QUESTION_ANSWERS, null);
|
|
context.commit(storeMutations.UPDATE_CAPABILITY_QUESTION_ANSWERS, null);
|
|
context.commit(storeMutations.UPDATE_PAGE_DATA, {
|
|
page: routeData.MOLDING_QUESTIONS.name,
|
|
data: null,
|
|
});
|
|
context.commit(storeMutations.UPDATE_PAGE_DATA, {
|
|
page: routeData.CAPABILITY_QUESTIONS.name,
|
|
data: null,
|
|
});
|
|
}
|
|
},
|
|
|
|
saveMoldingQuestionAnswers(context, moldingQuestionAnswers) {
|
|
const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(
|
|
context.getters.damage.moldingQuestionAnswers,
|
|
"partNum"
|
|
);
|
|
const sortedMoldingQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(
|
|
moldingQuestionAnswers,
|
|
"partNum"
|
|
);
|
|
const haveMoldingQuestionAnswersChanged =
|
|
sortedPreviousResultsArray?.length !== sortedMoldingQuestionAnswersArray.length ||
|
|
!sortedPreviousResultsArray?.every(
|
|
(x, i) => x.partNum === sortedMoldingQuestionAnswersArray[i].partNum
|
|
);
|
|
|
|
if (haveMoldingQuestionAnswersChanged) {
|
|
context.dispatch(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES);
|
|
|
|
context.commit(storeMutations.UPDATE_GLASS_PARTS, null);
|
|
context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null);
|
|
context.commit(storeMutations.UPDATE_CAPABILITY_QUESTION_ANSWERS, null);
|
|
context.commit(storeMutations.UPDATE_PAGE_DATA, {
|
|
page: routeData.CAPABILITY_QUESTIONS.name,
|
|
data: null,
|
|
});
|
|
}
|
|
|
|
//Save new values
|
|
context.commit(storeMutations.UPDATE_MOLDING_QUESTION_ANSWERS, moldingQuestionAnswers);
|
|
},
|
|
|
|
saveCapabilityQuestionAnswers(context, capabilityQuestionAnswers) {
|
|
const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(
|
|
context.getters.damage.capabilityQuestionAnswers,
|
|
"result"
|
|
);
|
|
const sortedCapabilityQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(
|
|
capabilityQuestionAnswers,
|
|
"result"
|
|
);
|
|
const haveCapabilityQuestionAnswersChanged =
|
|
sortedPreviousResultsArray?.length !== sortedCapabilityQuestionAnswersArray.length ||
|
|
!sortedPreviousResultsArray?.every(
|
|
(x, i) => x.result === sortedCapabilityQuestionAnswersArray[i].result
|
|
);
|
|
|
|
if (haveCapabilityQuestionAnswersChanged) {
|
|
context.dispatch(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES);
|
|
|
|
context.commit(storeMutations.UPDATE_GLASS_PARTS, null);
|
|
context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null);
|
|
}
|
|
|
|
//Save new values
|
|
context.commit(
|
|
storeMutations.UPDATE_CAPABILITY_QUESTION_ANSWERS,
|
|
capabilityQuestionAnswers
|
|
);
|
|
},
|
|
|
|
savePaymentType(context, isInsurance) {
|
|
if (isInsurance !== context.getters.payment.isInsurance) {
|
|
context.commit(storeMutations.RESET_PAYMENT_METHOD_CHOICE);
|
|
}
|
|
|
|
context.commit(storeMutations.UPDATE_IS_INSURANCE, isInsurance);
|
|
},
|
|
|
|
savePaymentMethodChoice(context, paymentMethod) {
|
|
var isPia = null;
|
|
if (paymentMethod !== paymentMethods.NONE) {
|
|
isPia = paymentMethod !== paymentMethods.LATER;
|
|
}
|
|
|
|
context.commit(storeMutations.UPDATE_IS_PIA, isPia);
|
|
context.commit(storeMutations.UPDATE_PIA_TYPE, isPia ? paymentMethod : null);
|
|
},
|
|
|
|
saveIsRecalAckOptIn(context, isRecalAckOptIn) {
|
|
context.commit(storeMutations.UPDATE_IS_RECAL_ACK_OPT_IN, isRecalAckOptIn);
|
|
},
|
|
|
|
saveIsRecalAcknowledgedForScheduling(context, isRecalAcknowledgedForScheduling) {
|
|
context.commit(
|
|
storeMutations.UPDATE_IS_RECAL_ACKNOWLEDGED_FOR_SCHEDULING,
|
|
isRecalAcknowledgedForScheduling
|
|
);
|
|
},
|
|
|
|
saveIsOemGlassSelected(context, isOemGlassSelected) {
|
|
context.commit(storeMutations.UPDATE_IS_OEM_GLASS_SELECTED, isOemGlassSelected);
|
|
},
|
|
|
|
saveIsMSRFeeApplicable(context, isMSRFeeApplicable) {
|
|
context.commit(storeMutations.UPDATE_IS_MSR_FEE_APPLICABLE, isMSRFeeApplicable);
|
|
},
|
|
|
|
saveIsMSRFeeCoveredByInsurance(context, isMSRFeeCoveredByInsurance) {
|
|
context.commit(
|
|
storeMutations.UPDATE_IS_MSR_FEE_COVERED_BY_INSURANCE,
|
|
isMSRFeeCoveredByInsurance
|
|
);
|
|
},
|
|
|
|
saveIsNewInsuranceFlow(context, isNewInsuranceFlow) {
|
|
context.commit(storeMutations.UPDATE_IS_NEW_INSURANCE_FLOW, isNewInsuranceFlow);
|
|
},
|
|
|
|
saveParentAccountNumber(context, parentAccountNumber) {
|
|
context.commit(storeMutations.UPDATE_PARENT_ACCT_NUMBER, parentAccountNumber);
|
|
},
|
|
saveAccountName(context, accountName) {
|
|
context.commit(storeMutations.UPDATE_ACCOUNT_NAME, accountName);
|
|
},
|
|
saveInsuranceAccountDetails(
|
|
context,
|
|
{ isClaimAndCoverage, canScheduleOnline, isManagedAccount }
|
|
) {
|
|
context.commit(storeMutations.UPDATE_IS_CLAIM_AND_COVERAGE, isClaimAndCoverage);
|
|
context.commit(storeMutations.UPDATE_CAN_SCHEDULE_ONLINE, canScheduleOnline);
|
|
context.commit(storeMutations.UPDATE_IS_MANAGED_ACCOUNT, isManagedAccount);
|
|
},
|
|
saveBillToAccountNumber(context, billToAccountNumber) {
|
|
context.commit(storeMutations.UPDATE_BILL_TO_ACCT_NUMBER, billToAccountNumber);
|
|
},
|
|
resetInsuranceDetails(context) {
|
|
context.commit(storeMutations.RESET_INSURANCE_DETAILS);
|
|
},
|
|
|
|
saveSupportingItems(context, supportingItems) {
|
|
syncLineItemIds(supportingItems, context.state.order.lineItems.supportingItems);
|
|
if (!supportingItemsEqual(supportingItems, context.state.order.lineItems.supportingItems)) {
|
|
context.dispatch(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES);
|
|
}
|
|
addGuidToLineItemsIfNotAlreadyThere(supportingItems);
|
|
context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, supportingItems);
|
|
},
|
|
|
|
saveSupportingItemsSuppressingStateResetting(context, supportingItems) {
|
|
addGuidToLineItemsIfNotAlreadyThere(supportingItems);
|
|
context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, supportingItems);
|
|
},
|
|
saveVaps(context, vaps) {
|
|
addGuidToLineItemsIfNotAlreadyThere(vaps);
|
|
context.commit(storeMutations.UPDATE_VAPS, vaps);
|
|
},
|
|
// Manage promo saving to ensure a promoCode never ends up in both active and inactive
|
|
saveActiveAndOrInactivePromos(context, { activePromos = null, inactivePromos = null }) {
|
|
if (inactivePromos) {
|
|
// Clean up inactivePromos
|
|
// Remove bundle identifier
|
|
inactivePromos = inactivePromos.map((promoCode) =>
|
|
getPromoCodeWithoutBundleIdentifier(promoCode)
|
|
);
|
|
// Remove duplicates
|
|
inactivePromos = inactivePromos.filter(
|
|
(promoCode, index) => inactivePromos.indexOf(promoCode) === index
|
|
);
|
|
}
|
|
activePromos = activePromos?.slice(0);
|
|
inactivePromos = inactivePromos?.slice(0);
|
|
let activePromosToSave;
|
|
let inactivePromosToSave;
|
|
if (!activePromos && !inactivePromos) {
|
|
// Allow double null to save empty arrays to store
|
|
activePromosToSave = [];
|
|
inactivePromosToSave = [];
|
|
} else if (activePromos && inactivePromos) {
|
|
// Prioritize active promos when both inactive and active are supplied
|
|
activePromosToSave = activePromos;
|
|
inactivePromosToSave = removeCurrentlyActivePromoCodesFromInactivePromos(
|
|
activePromosToSave,
|
|
inactivePromos
|
|
);
|
|
} else if (!activePromos) {
|
|
// Only inactivePromos supplied
|
|
inactivePromosToSave = inactivePromos;
|
|
activePromosToSave = (context.getters.lineItems.promos ?? []).filter((activePromo) => {
|
|
return !inactivePromosToSave.includes(
|
|
getPromoCodeWithoutBundleIdentifier(activePromo.promoCode)
|
|
);
|
|
});
|
|
} else if (!inactivePromos) {
|
|
// Only activePromos supplied
|
|
activePromosToSave = activePromos;
|
|
inactivePromosToSave = removeCurrentlyActivePromoCodesFromInactivePromos(
|
|
activePromosToSave,
|
|
context.getters.payment.inactivePromos ?? []
|
|
);
|
|
}
|
|
context.commit(storeMutations.UPDATE_PROMOS, activePromosToSave);
|
|
context.commit(storeMutations.UPDATE_INACTIVE_PROMOS, inactivePromosToSave);
|
|
},
|
|
|
|
// Price order actions
|
|
async priceOrderItemsAndSaveServerData(
|
|
context,
|
|
{ payload: { availableLineItems, serviceZipCode, serviceZipCodeCtu }, pageNameToLog }
|
|
) {
|
|
const flattenedLineItemsWithChildParts =
|
|
getFlattenedArrayOfLineItemsWithChildParts(availableLineItems);
|
|
|
|
const lineItemsWithOnlyPartNumbers = flattenedLineItemsWithChildParts.map((lineItem) => ({
|
|
partNumber: lineItem.partNumber,
|
|
}));
|
|
|
|
const order = context.getters.order;
|
|
|
|
var providerNumber =
|
|
order.serviceLocation?.provider?.providerNumber ?? order.serviceLocation?.zipCodeCtu;
|
|
if (providerNumber.startsWith("00") && providerNumber.length > 5) {
|
|
providerNumber = providerNumber.substring(1);
|
|
}
|
|
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.PriceOrderItems.method,
|
|
endpoint: endpoints.PriceOrderItems.url,
|
|
payload: {
|
|
parentAccountNumber: order.payment?.parentAccountNumber,
|
|
billToAccountNumber:
|
|
order.payment?.billToAccountNumber ??
|
|
applicationConfig.CASH_DEFAULT_BILL_TO_ACCOUNT_NUMBER,
|
|
providerNumber: providerNumber,
|
|
carId: order.vehicle.carId,
|
|
year: order.vehicle.year,
|
|
make: order.vehicle.make,
|
|
model: order.vehicle.model,
|
|
eon: order.eon,
|
|
state: order.serviceLocation?.state,
|
|
referralNumber: order.referralNumber,
|
|
referralSequenceNumber: order.referralSequenceNumber,
|
|
zipCode: order.serviceLocation?.zipCode,
|
|
serviceZipCode: serviceZipCode ?? order.serviceLocation?.zipCode,
|
|
referralDate: order.referralDate,
|
|
isReplacement: !order.damage.isRepair,
|
|
deductible: order.policy?.currentDeductible,
|
|
coverageStatus: order.payment?.insuranceCoverage?.coverageStatus,
|
|
lineItems: lineItemsWithOnlyPartNumbers,
|
|
serverData: order.lineItems.serverData ? order.lineItems.serverData : "",
|
|
},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
|
|
context.commit(storeMutations.UPDATE_LINE_ITEMS_SERVER_DATA, response.data.serverData);
|
|
|
|
availableLineItems = addPricesToLineItems(availableLineItems, response.data.lineItems);
|
|
|
|
return availableLineItems;
|
|
},
|
|
|
|
// Tax order actions
|
|
async taxOrderItemsAndSaveServerData(
|
|
context,
|
|
{
|
|
payload: {
|
|
billToAccountNumber,
|
|
providerNumber,
|
|
appointmentType,
|
|
serviceLocationCity,
|
|
serviceLocationState,
|
|
serviceLocationZipCode,
|
|
pricedLineItems,
|
|
serviceLocationAddressLine1,
|
|
serviceLocationAddressLine2,
|
|
},
|
|
pageNameToLog,
|
|
}
|
|
) {
|
|
const arrayOfLineItems = [
|
|
...(pricedLineItems.glassParts ?? []),
|
|
...(pricedLineItems.promos ?? []),
|
|
...(pricedLineItems.supportingItems ?? []),
|
|
...(pricedLineItems.vaps ?? []),
|
|
];
|
|
const flattenedLineItemsWithChildParts =
|
|
getFlattenedArrayOfLineItemsWithChildParts(arrayOfLineItems);
|
|
|
|
const lineItemsWithOnlyPriceInfo = flattenedLineItemsWithChildParts.map((lineItem) => ({
|
|
partNumber: lineItem.partNumber,
|
|
laborAmount: lineItem.laborAmount ?? 0,
|
|
kitPrice: lineItem.kitPrice ?? 0,
|
|
sellingPrice: lineItem.sellingPrice ?? 0,
|
|
promoCode: lineItem.promoCode ?? null,
|
|
}));
|
|
|
|
const order = context.getters.order;
|
|
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.TaxOrderItems.method,
|
|
endpoint: endpoints.TaxOrderItems.url,
|
|
payload: {
|
|
parentAccountNumber: order.payment.parentAccountNumber,
|
|
billToAccountNumber: billToAccountNumber,
|
|
providerNumber: providerNumber,
|
|
appointmentType: appointmentType,
|
|
pricedLineItems: lineItemsWithOnlyPriceInfo,
|
|
serviceLocation: {
|
|
addressLine1: appointmentType == "Mobile" ? serviceLocationAddressLine1 : null,
|
|
addressLine2: appointmentType == "Mobile" ? serviceLocationAddressLine2 : null,
|
|
city: appointmentType == "Mobile" ? serviceLocationCity : null,
|
|
state: appointmentType == "Mobile" ? serviceLocationState : null,
|
|
zipCode: appointmentType == "Mobile" ? serviceLocationZipCode : null,
|
|
},
|
|
serverData: order.lineItems.serverData ? order.lineItems.serverData : "",
|
|
},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
|
|
context.commit(storeMutations.UPDATE_LINE_ITEMS_SERVER_DATA, response.data.serverData);
|
|
Object.keys(pricedLineItems).forEach((key) => {
|
|
pricedLineItems[key] = addTaxesToPricedLineItems(
|
|
pricedLineItems[key] ?? [],
|
|
response.data.taxedLineItems
|
|
);
|
|
});
|
|
|
|
return pricedLineItems;
|
|
},
|
|
|
|
// The <addableVaps> parameter is an array of ALL available front wipers and Rain Repel
|
|
// for the vehicle. There is no need to confirm an addableVap is not already on the order
|
|
// <lineItemsToUse> is an optional parameter if the lineItems in the store may not be up to date
|
|
async validateOrderPromoAndSaveServerData(
|
|
context,
|
|
{
|
|
payload: {
|
|
promoCode,
|
|
lineItemsToUse,
|
|
addableVaps,
|
|
useDefaultCashParentAccount = false,
|
|
},
|
|
pageNameToLog,
|
|
}
|
|
) {
|
|
const order = context.getters.order;
|
|
lineItemsToUse = lineItemsToUse ?? order.lineItems;
|
|
addGuidToLineItemsIfNotAlreadyThere(lineItemsToUse.vaps);
|
|
syncLineItemIds(addableVaps, lineItemsToUse.vaps);
|
|
// addableVaps still won't have IDs if they weren't already in lineItemsToUse
|
|
addGuidToLineItemsIfNotAlreadyThere(addableVaps);
|
|
const requestObject = {
|
|
promoCode: promoCode,
|
|
addableVaps: addableVaps,
|
|
order: {
|
|
appointmentType: order.serviceLocation.appointmentType,
|
|
carId: order.vehicle.carId,
|
|
correlationId: order.referralCorrelationId,
|
|
eon: order.eon,
|
|
isInsurance: order.payment.isInsurance,
|
|
isRepair: order.damage.isRepair,
|
|
glassToReplace: renameGlassToReplaceAttributes(order.damage.glassToReplace),
|
|
lineItemsOnOrder: getArrayOfAllLineItemsAndChildParts(lineItemsToUse),
|
|
parentAccountNumber: useDefaultCashParentAccount
|
|
? applicationConfig.CASH_PARENT_ACCOUNT_NUMBER
|
|
: order.payment.parentAccountNumber,
|
|
referralSequenceNumber: order.referralSequenceNumber,
|
|
serviceState: order.serviceLocation.state,
|
|
serverData: order.lineItems.serverData,
|
|
vehicleYear: "" + order.vehicle.year,
|
|
zipCodeOrProviderCtu:
|
|
order.serviceLocation.appointmentType === "Inshop"
|
|
? order.serviceLocation.provider.address.zipCodeCtu
|
|
: order.serviceLocation.zipCodeCtu,
|
|
},
|
|
};
|
|
|
|
const validateResponse = await globalMethods
|
|
.callHttpClient({
|
|
method: endpoints.ValidatePromo.method,
|
|
endpoint: endpoints.ValidatePromo.url,
|
|
payload: requestObject,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
})
|
|
.catch((error) => {
|
|
// Validate promo will return 4xx errors when an invalid promo
|
|
return error;
|
|
});
|
|
|
|
if (validateResponse?.data?.serverData) {
|
|
context.commit(
|
|
storeMutations.UPDATE_LINE_ITEMS_SERVER_DATA,
|
|
validateResponse.data.serverData
|
|
);
|
|
}
|
|
|
|
return validateResponse?.data;
|
|
},
|
|
// All payload parameters are optional - will use store data if not provided
|
|
async revalidateOrderPromosAndSaveServerData(
|
|
context,
|
|
{
|
|
payload: {
|
|
activePromosToUse,
|
|
inactivePromosToUse,
|
|
lineItemsToUse,
|
|
useDefaultCashParentAccount = false,
|
|
},
|
|
pageNameToLog,
|
|
}
|
|
) {
|
|
const order = context.getters.order;
|
|
|
|
activePromosToUse = activePromosToUse ?? order.lineItems.promos;
|
|
lineItemsToUse = lineItemsToUse ? deepClone(lineItemsToUse) : deepClone(order.lineItems);
|
|
addGuidToLineItemsIfNotAlreadyThere(lineItemsToUse.vaps);
|
|
lineItemsToUse.promos = activePromosToUse;
|
|
|
|
inactivePromosToUse = inactivePromosToUse ?? order.payment.inactivePromos;
|
|
inactivePromosToUse = removeCurrentlyActivePromoCodesFromInactivePromos(
|
|
lineItemsToUse.promos,
|
|
inactivePromosToUse
|
|
);
|
|
|
|
let requestObject = {
|
|
inactivePromos: inactivePromosToUse,
|
|
order: {
|
|
appointmentType: order.serviceLocation.appointmentType,
|
|
carId: order.vehicle.carId,
|
|
correlationId: order.referralCorrelationId,
|
|
eon: order.eon,
|
|
isInsurance: order.payment.isInsurance,
|
|
isRepair: order.damage.isRepair,
|
|
glassToReplace: renameGlassToReplaceAttributes(order.damage.glassToReplace),
|
|
lineItemsOnOrder: getArrayOfAllLineItemsAndChildParts(lineItemsToUse),
|
|
parentAccountNumber: useDefaultCashParentAccount
|
|
? applicationConfig.CASH_PARENT_ACCOUNT_NUMBER
|
|
: order.payment.parentAccountNumber,
|
|
referralSequenceNumber: order.referralSequenceNumber,
|
|
serviceState: order.serviceLocation.state,
|
|
serverData: order.lineItems.serverData,
|
|
vehicleYear: "" + order.vehicle.year,
|
|
zipCodeOrProviderCtu:
|
|
order.serviceLocation.appointmentType === "Inshop"
|
|
? order.serviceLocation.provider.address.zipCodeCtu
|
|
: order.serviceLocation.zipCodeCtu,
|
|
},
|
|
};
|
|
|
|
const revalidateResponse = await globalMethods.callHttpClient({
|
|
method: endpoints.RevalidatePromos.method,
|
|
endpoint: endpoints.RevalidatePromos.url,
|
|
payload: requestObject,
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
|
|
context.commit(
|
|
storeMutations.UPDATE_LINE_ITEMS_SERVER_DATA,
|
|
revalidateResponse.data.lineItemsServerData
|
|
);
|
|
|
|
return revalidateResponse?.data;
|
|
},
|
|
///////////////////////////
|
|
// Account Service Calls //
|
|
///////////////////////////
|
|
|
|
// List all insurance companies
|
|
async getInsuranceCompanyList(context, { pageNameToLog }) {
|
|
const insuranceCompanyList = await globalMethods.callHttpClient({
|
|
method: endpoints.GetInsuranceCompanyList.method,
|
|
endpoint: endpoints.GetInsuranceCompanyList.url,
|
|
payload: {},
|
|
logApiCall: true,
|
|
pageNameToLog: pageNameToLog,
|
|
});
|
|
|
|
return insuranceCompanyList.data.sort((a, b) => {
|
|
const nameA = a.accountName.toUpperCase();
|
|
const nameB = b.accountName.toUpperCase();
|
|
if (nameA < nameB) {
|
|
return -1;
|
|
}
|
|
if (nameA > nameB) {
|
|
return 1;
|
|
}
|
|
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,
|
|
}
|
|
) {
|
|
if (!parentAccountNumber) {
|
|
parentAccountNumber = applicationConfig.CASH_PARENT_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();
|
|
},
|
|
// Get Account Details
|
|
async getAccountDetails(context, { payload: { parentAccountNumber }, pageNameToLog }) {
|
|
const accountDetailsResponse = await globalMethods.callHttpClient({
|
|
method: endpoints.GetAccountDetails.method,
|
|
endpoint: `${endpoints.GetAccountDetails.url}/${parentAccountNumber}`,
|
|
});
|
|
|
|
return accountDetailsResponse.data;
|
|
},
|
|
//////////////////////////////////
|
|
// END OF Account Service Calls //
|
|
//////////////////////////////////
|
|
|
|
// Misc order actions
|
|
saveSchedule(context, scheduleInfo) {
|
|
context.commit(storeMutations.UPDATE_SCHEDULE, scheduleInfo);
|
|
},
|
|
|
|
saveCustomerDetails(context, customerDetails) {
|
|
context.commit(storeMutations.UPDATE_CUSTOMER_DETAILS, customerDetails);
|
|
},
|
|
|
|
saveInsuranceDetails(context, insuranceDetails) {
|
|
context.commit(storeMutations.UPDATE_INSURANCE_DETAILS, insuranceDetails);
|
|
},
|
|
|
|
saveDamageDetails(context, damageDetails) {
|
|
context.commit(storeMutations.UPDATE_DAMAGE_DETAILS, damageDetails);
|
|
},
|
|
|
|
saveServiceZipCodeInfo(context, serviceZipCodeInfo) {
|
|
if (
|
|
context.state.order.serviceLocation &&
|
|
serviceZipCodeInfo.zipCode !== context.state.order.serviceLocation.zipCode
|
|
) {
|
|
context.dispatch(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES);
|
|
|
|
context.commit(storeMutations.RESET_SERVICE_LOCATION_MOBILE_ADDRESS);
|
|
}
|
|
|
|
context.commit(storeMutations.UPDATE_SERVICE_ZIP, serviceZipCodeInfo);
|
|
},
|
|
|
|
saveServiceLocation(context, serviceLocationInfo) {
|
|
if (context.state.order.serviceLocation) {
|
|
if (
|
|
serviceLocationInfo.zipCode !== context.state.order.serviceLocation.zipCode ||
|
|
!providersEqual(
|
|
serviceLocationInfo.provider,
|
|
context.state.order.serviceLocation.provider
|
|
) ||
|
|
serviceLocationInfo.appointmentType !==
|
|
context.state.order.serviceLocation.appointmentType
|
|
) {
|
|
context.commit(storeMutations.RESET_SCHEDULE);
|
|
context.commit(storeMutations.RESET_PAYMENT_METHOD_CHOICE);
|
|
}
|
|
}
|
|
|
|
context.commit(storeMutations.UPDATE_SERVICE_LOCATION, serviceLocationInfo);
|
|
},
|
|
saveMobileDetails(context, mobileDetails) {
|
|
context.commit(storeMutations.UPDATE_MOBILE_DETAILS, mobileDetails);
|
|
},
|
|
|
|
saveServiceLocationTechNotes(context, techNotesInfo) {
|
|
context.commit(storeMutations.UPDATE_SERVICE_LOCATION_TECH_NOTES, techNotesInfo);
|
|
},
|
|
|
|
saveEmail(context, email) {
|
|
context.commit(storeMutations.UPDATE_CUSTOMER_EMAIL_ADDRESS, email === "" ? null : email);
|
|
},
|
|
|
|
savePhoneNumber(context, phoneNumber) {
|
|
context.commit(
|
|
storeMutations.UPDATE_CUSTOMER_PHONE_NUMBER,
|
|
phoneNumber === "" ? null : phoneNumber
|
|
);
|
|
},
|
|
saveIsSmsOptIn(context, isSmsOptIn) {
|
|
context.commit(storeMutations.UPDATE_CUSTOMER_IS_SMS_OPT_IN, isSmsOptIn);
|
|
},
|
|
|
|
saveWaitListRequested(context, waitListRequested) {
|
|
context.commit(storeMutations.UPDATE_CUSTOMER_WAITLIST_REQUESTED, waitListRequested);
|
|
},
|
|
|
|
savePageData(context, pageData) {
|
|
context.commit(storeMutations.UPDATE_PAGE_DATA, pageData);
|
|
},
|
|
|
|
saveVin(context, { isSelectedGlassAvailableForVehicle, vehicleInfo }) {
|
|
//Reset dependent state when changing
|
|
if (vehicleInfo.vin !== context.state.order.vehicle.vin) {
|
|
if (!isSelectedGlassAvailableForVehicle) {
|
|
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
|
}
|
|
|
|
//Save new values
|
|
context.commit(storeMutations.UPDATE_VEHICLE, vehicleInfo);
|
|
}
|
|
},
|
|
|
|
saveGlassParts(context, parts) {
|
|
if (!deepEqual(parts, context.state.order.lineItems.glassParts)) {
|
|
context.dispatch(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES);
|
|
}
|
|
addGuidToLineItemsIfNotAlreadyThere(parts);
|
|
context.commit(storeMutations.UPDATE_GLASS_PARTS, parts);
|
|
},
|
|
|
|
saveGlassPartsSuppressingStateResetting(context, parts) {
|
|
context.commit(storeMutations.UPDATE_GLASS_PARTS, parts);
|
|
},
|
|
|
|
clearVin(context) {
|
|
context.commit(storeMutations.UPDATE_VEHICLE_VIN, null);
|
|
},
|
|
|
|
isVinOptionalVehicle(context) {
|
|
if (context.state.order.vehicle.skipVINLookup) return true;
|
|
|
|
return false;
|
|
},
|
|
|
|
createSubmittedState(context) {
|
|
if (window.sessionStorage.getItem(sessionStorageKeyConstants.SUBMITTED_STATE) !== null) {
|
|
return;
|
|
}
|
|
|
|
// create a submitted order object from vuex.
|
|
const submittedState = {
|
|
order: context.state.order,
|
|
applicationUser: context.state.applicationUser,
|
|
};
|
|
|
|
const experiments = context.state.applicationUser.experiments;
|
|
const affiliateCookies = context.state.applicationUser.affiliateCookies;
|
|
|
|
// set to local storage
|
|
window.sessionStorage.setItem(
|
|
sessionStorageKeyConstants.SUBMITTED_STATE,
|
|
JSON.stringify(submittedState)
|
|
);
|
|
window.sessionStorage.setItem("createNewSessionForHeritage", true);
|
|
|
|
// clear vuex
|
|
context.commit(storeMutations.RESET_STATE);
|
|
|
|
// delete cookie
|
|
deleteFunnelCookie();
|
|
|
|
//restore user's experiments
|
|
context.commit(storeMutations.UPDATE_EXPERIMENTS, experiments);
|
|
|
|
//clear externalParameter session storage
|
|
window.sessionStorage.removeItem(sessionStorageKeyConstants.EXTERNAL_PARAMETER_STATE);
|
|
|
|
//restore affiliate cookies
|
|
context.commit(storeMutations.UPDATE_AFFILIATE_COOKIES, affiliateCookies);
|
|
|
|
context.commit(storeMutations.INCREMENT_SUBMITTED_STATE_REVISION);
|
|
},
|
|
|
|
addDonationToSubmittedState(context, donationAmount) {
|
|
const submittedOrder = deepClone(baseMixin.methods.getSubmittedOrder());
|
|
const submittedApplicationUser = deepClone(baseMixin.methods.getSubmittedApplicationUser());
|
|
|
|
submittedOrder.lineItems.supportingItems.push({
|
|
partNumber: `DONATION_${donationAmount}`,
|
|
description: `DONATION $${donationAmount}`,
|
|
partType: partTypeStrings.DONATION,
|
|
isInsurable: false,
|
|
isChildPart: false,
|
|
laborAmount: 0,
|
|
sellingPrice: donationAmount,
|
|
kitPrice: 0,
|
|
salesTax: 0,
|
|
});
|
|
|
|
addGuidToLineItemsIfNotAlreadyThere(submittedOrder.lineItems.supportingItems);
|
|
|
|
const submittedState = {
|
|
order: submittedOrder,
|
|
applicationUser: submittedApplicationUser,
|
|
};
|
|
// set to local storage
|
|
window.sessionStorage.setItem(
|
|
sessionStorageKeyConstants.SUBMITTED_STATE,
|
|
JSON.stringify(submittedState)
|
|
);
|
|
|
|
context.commit(storeMutations.INCREMENT_SUBMITTED_STATE_REVISION);
|
|
},
|
|
|
|
resetSubmittedState(context) {
|
|
// clear from local storage
|
|
window.sessionStorage.removeItem(sessionStorageKeyConstants.SUBMITTED_STATE);
|
|
|
|
context.commit(storeMutations.INCREMENT_SUBMITTED_STATE_REVISION);
|
|
},
|
|
resetExternalParameterState(context) {
|
|
if (context.getters.isExternalParameter) {
|
|
context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_VEHICLE_STATE);
|
|
context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_DAMAGE_STATE);
|
|
context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_ESTIMATE_STATE);
|
|
context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_SERVICEZIP_STATE);
|
|
context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_QUOTE_STATE);
|
|
context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_CUSTOMER_STATE);
|
|
context.commit(storeMutations.RESET_IS_EXTERNAL_PARAMETER);
|
|
}
|
|
},
|
|
updateExternalParameterMMS(context, externalParameterMMS) {
|
|
context.commit(
|
|
storeMutations.UPDATE_EXTERNAL_PARAMETER_MAKE,
|
|
externalParameterMMS.externalParameterMake
|
|
);
|
|
context.commit(
|
|
storeMutations.UPDATE_EXTERNAL_PARAMETER_MODEL,
|
|
externalParameterMMS.externalParameterModel
|
|
);
|
|
context.commit(
|
|
storeMutations.UPDATE_EXTERNAL_PARAMETER_STYLE,
|
|
externalParameterMMS.externalParameterStyle
|
|
);
|
|
},
|
|
|
|
saveLoggingOption(context, loggingOption) {
|
|
var option = false;
|
|
if (loggingOption != null) {
|
|
option = loggingOption == "true" ? true : false;
|
|
}
|
|
|
|
context.commit(storeMutations.UPDATE_LOGGING_OPTION, option);
|
|
},
|
|
|
|
async getRecalPartsAndSaveToLineItems(context, { pageNameToLog }) {
|
|
// identify each part that needs recal
|
|
const glassParts = context.state.order?.lineItems?.glassParts
|
|
? deepClone(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);
|
|
context.dispatch(storeActions.SAVE_GLASS_PARTS, glassParts);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
updateHasTriggeredError(context, hasAlreadyTriggeredError) {
|
|
context.commit(storeMutations.UPDATE_HAS_TRIGGERED_ERROR, hasAlreadyTriggeredError);
|
|
},
|
|
|
|
getValidIdempotencyKey(context) {
|
|
if (context.getters.isIdempotencyKeyValid) {
|
|
return context.state.idempotencyKeyFields.idempotencyKey;
|
|
}
|
|
|
|
// If invalid, need to regenerate.
|
|
const referralCorrelationId = context.state.order?.referralCorrelationId;
|
|
if (!referralCorrelationId) {
|
|
// Can't generate!
|
|
return null;
|
|
}
|
|
|
|
const total = getAmountDue(context.state.order?.lineItems);
|
|
const totalInCents = Math.round(total * 100);
|
|
if (Number.isNaN(totalInCents)) {
|
|
// Can't generate!
|
|
return null;
|
|
}
|
|
|
|
const currentTime = new Date();
|
|
const nextHour = currentTime.getUTCHours() + 1;
|
|
currentTime.setUTCHours(nextHour);
|
|
|
|
const newId = crypto.randomUUID();
|
|
|
|
const newKeyInfo = {
|
|
idempotencyKey: newId,
|
|
referralCorrelationId: referralCorrelationId,
|
|
totalInCents: totalInCents,
|
|
expiryTime: currentTime,
|
|
};
|
|
|
|
context.commit(storeMutations.UPDATE_IDEMPOTENCY_KEY, newKeyInfo);
|
|
|
|
return newId;
|
|
},
|
|
|
|
correctIdempotencyKeyExpiry(context, expiryTime) {
|
|
if (!context.getters.isIdempotencyKeyValid) {
|
|
return;
|
|
}
|
|
|
|
const currentExpiryTime = new Date(context.state.idempotencyKeyFields.expiryTime);
|
|
const expiryTimeAsDate = new Date(expiryTime);
|
|
|
|
if (expiryTimeAsDate.getTime() < currentExpiryTime.getTime()) {
|
|
const existingKey = context.state.idempotencyKeyFields;
|
|
const newKey = {
|
|
referralCorrelationId: existingKey.referralCorrelationId,
|
|
totalInCents: existingKey.totalInCents,
|
|
idempotencyKey: existingKey.idempotencyKey,
|
|
expiryTime: expiryTimeAsDate,
|
|
};
|
|
context.commit(storeMutations.UPDATE_IDEMPOTENCY_KEY, newKey);
|
|
}
|
|
},
|
|
};
|
|
|
|
export default createStore({
|
|
plugins: [
|
|
createPersistedState(),
|
|
sharedMutations({
|
|
predicate: [...Object.values(storeMutations)],
|
|
}),
|
|
],
|
|
// IMPORTANT: Be VERY careful when modifying these fields for at least a few reasons:
|
|
// * The CMS can reference the fields by name
|
|
// * Return users may have a previous "version" of the model, and we don't want
|
|
// them to have a breaking experience, because the model might have changed.
|
|
state,
|
|
mutations,
|
|
getters,
|
|
actions,
|
|
});
|
|
|
|
export function mapTaxedLineItemsToStoreFormat(availableLineItems, storeLineItems) {
|
|
// clone the lineItems array because what we're passing in is referencing the store directly
|
|
const lineItems = deepClone(storeLineItems);
|
|
|
|
for (let [category, lineItemsInCategory] of Object.entries(lineItems)) {
|
|
lineItemsInCategory = lineItemsInCategory ?? [];
|
|
|
|
if (category == "supportingItems") {
|
|
// if the category is supporting items we need to filter out the items that aren't repair chips
|
|
const nonRepairChipSupportItemsLineItems = lineItemsInCategory.filter(
|
|
(lineItem) => lineItem.partNumber != "WSREPAIR"
|
|
);
|
|
|
|
/*
|
|
Because repair chips all have the same part number but different prices based on the quantity,
|
|
we have to sort the store line items and available line items by descending labor amount in order to
|
|
map the tax correctly to each repair chip
|
|
*/
|
|
// get the supporting items that ARE repair chips and sort them by descending labor amount
|
|
let repairChipLineItems = lineItemsInCategory.filter(
|
|
(lineItem) => lineItem.partNumber == "WSREPAIR"
|
|
);
|
|
repairChipLineItems = repairChipLineItems.sort(
|
|
(a, b) => parseFloat(b.laborAmount) - parseFloat(a.laborAmount)
|
|
);
|
|
|
|
// get the supporting items from the available line items (taxed) that ARE repair chips and sort them by descending labor amount
|
|
let availableRepairChipLineItems = availableLineItems.filter(
|
|
(lineItem) => lineItem.partNumber == "WSREPAIR"
|
|
);
|
|
availableRepairChipLineItems = availableRepairChipLineItems.sort(
|
|
(a, b) => parseFloat(b.laborAmount) - parseFloat(a.laborAmount)
|
|
);
|
|
|
|
// go through each one of those mapping the taxes to the correct chip
|
|
for (let i = 0; i < availableRepairChipLineItems.length; i++) {
|
|
repairChipLineItems[i].salesTax = availableRepairChipLineItems[i].salesTax;
|
|
}
|
|
|
|
// then we map the non-repair chip items based on part number
|
|
for (
|
|
let lineItemIndex = 0;
|
|
lineItemIndex < nonRepairChipSupportItemsLineItems.length;
|
|
lineItemIndex++
|
|
) {
|
|
const availableLineItem = availableLineItems.find(
|
|
(ali) =>
|
|
ali.partNumber ==
|
|
nonRepairChipSupportItemsLineItems[lineItemIndex].partNumber
|
|
);
|
|
if (availableLineItem) {
|
|
nonRepairChipSupportItemsLineItems[lineItemIndex].salesTax =
|
|
availableLineItem.salesTax;
|
|
}
|
|
}
|
|
|
|
// finally we splice the two arrays back into one
|
|
lineItemsInCategory = nonRepairChipSupportItemsLineItems.concat(repairChipLineItems);
|
|
} else {
|
|
for (
|
|
let lineItemIndex = 0;
|
|
lineItemIndex < lineItemsInCategory.length;
|
|
lineItemIndex++
|
|
) {
|
|
const availableLineItem = availableLineItems.find(
|
|
(ali) => ali.partNumber == lineItemsInCategory[lineItemIndex].partNumber
|
|
);
|
|
if (availableLineItem) {
|
|
lineItemsInCategory[lineItemIndex].salesTax = availableLineItem.salesTax;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return lineItems;
|
|
}
|
|
|
|
export function getArrayOfAllLineItemsAndChildParts(lineItems) {
|
|
let consolidatedLineItemsArray = [];
|
|
|
|
if (lineItems?.glassParts != null)
|
|
consolidatedLineItemsArray = [
|
|
...consolidatedLineItemsArray,
|
|
...getFlattenedArrayOfLineItemsWithChildParts(lineItems.glassParts),
|
|
];
|
|
|
|
if (lineItems?.supportingItems != null)
|
|
consolidatedLineItemsArray = [
|
|
...consolidatedLineItemsArray,
|
|
...getFlattenedArrayOfLineItemsWithChildParts(lineItems.supportingItems),
|
|
];
|
|
|
|
if (lineItems?.vaps != null)
|
|
consolidatedLineItemsArray = [
|
|
...consolidatedLineItemsArray,
|
|
...getFlattenedArrayOfLineItemsWithChildParts(lineItems.vaps),
|
|
];
|
|
|
|
if (lineItems?.promos != null)
|
|
consolidatedLineItemsArray = [
|
|
...consolidatedLineItemsArray,
|
|
...getFlattenedArrayOfLineItemsWithChildParts(lineItems.promos),
|
|
];
|
|
|
|
return consolidatedLineItemsArray;
|
|
}
|
|
|
|
// Private Functions
|
|
|
|
function getNonFalseValuesOfPropertyInArrayOfObjects(array, propertyName) {
|
|
return (array ?? []).map((x) => x[propertyName]).filter((x) => x);
|
|
}
|
|
|
|
function getTimeSlotsAdditionalEventData(
|
|
provisionalTriggers,
|
|
zipCode,
|
|
firstAvailableAppointmentDateString,
|
|
shopAppointmentType
|
|
) {
|
|
var numberOfDays = null;
|
|
if (firstAvailableAppointmentDateString)
|
|
numberOfDays = getDateDifferenceInDays(
|
|
new Date().toISOString().split("T")[0],
|
|
firstAvailableAppointmentDateString
|
|
);
|
|
|
|
if (shopAppointmentType)
|
|
return `FirstAvailableAppointment:${numberOfDays},Zip:${zipCode},ShopAppointmentType:${shopAppointmentType},ProvisionalTriggers:${provisionalTriggers.join(
|
|
","
|
|
)}`;
|
|
else
|
|
return `FirstAvailableAppointment:${numberOfDays},Zip:${zipCode},ProvisionalTriggers:${provisionalTriggers.join(
|
|
","
|
|
)}`;
|
|
}
|
|
|
|
function getHasRecalibrationPart(state) {
|
|
return containsRecalParts(state.order.lineItems);
|
|
}
|
|
|
|
function sortArrayOfObjectsByPropertyValue(arrayOfObjects, propertyName) {
|
|
if (!arrayOfObjects) return null;
|
|
|
|
return arrayOfObjects.sort((a, b) => {
|
|
if (a[propertyName] < b[propertyName]) return -1;
|
|
else if (a[propertyName] > b[propertyName]) return 1;
|
|
else return 0;
|
|
});
|
|
}
|
|
|
|
function convertGlassPieceNamingForApi(glassArray) {
|
|
if (!glassArray || glassArray.length === 0) return [];
|
|
|
|
// check if array already converted. (likely when a session has been saved previously and then reloaded)
|
|
if (glassArray[0].location !== undefined) {
|
|
return glassArray;
|
|
}
|
|
|
|
const converted = [];
|
|
glassArray.forEach((glass) => {
|
|
converted.push({
|
|
location: glass.glassLocation,
|
|
name: glass.glassName,
|
|
});
|
|
});
|
|
return converted;
|
|
}
|
|
|
|
function convertResultsForApi(resultsArray) {
|
|
if (!resultsArray) return [];
|
|
const converted = [];
|
|
resultsArray.forEach((answer) => {
|
|
converted.push({
|
|
location: answer.glassLocation,
|
|
name: answer.glassName,
|
|
result: answer.result,
|
|
});
|
|
});
|
|
return converted;
|
|
}
|
|
|
|
function convertGlassPieceNamingFromApi(glassArray) {
|
|
glassArray.forEach((glass) => {
|
|
glass.glassLocation = glass.glassPiece.location;
|
|
glass.glassName = glass.glassPiece.name;
|
|
delete glass.glassPiece;
|
|
return glass;
|
|
});
|
|
return glassArray;
|
|
}
|
|
|
|
function addTaxesToPricedLineItems(pricedLineItems, taxingLineItems = []) {
|
|
pricedLineItems.forEach((pricedLineItem) => {
|
|
const lineItemIndex = taxingLineItems.findIndex(
|
|
(taxingLineItem) => taxingLineItem.partNumber === pricedLineItem.partNumber
|
|
);
|
|
|
|
if (pricedLineItem.childParts) {
|
|
addTaxesToPricedLineItems(pricedLineItem.childParts, taxingLineItems);
|
|
}
|
|
|
|
const taxedLineItem = taxingLineItems.splice(lineItemIndex, 1)[0];
|
|
pricedLineItem.salesTax = taxedLineItem?.salesTax ?? 0;
|
|
});
|
|
|
|
return pricedLineItems;
|
|
}
|
|
|
|
function getFlattenedArrayOfLineItemsWithChildParts(lineItems, childPartRecursiveCall = false) {
|
|
let flattenedArray = [];
|
|
lineItems?.forEach((lineItem) => {
|
|
// this assumes childparts will never be a glass part
|
|
lineItem.isChildPart = childPartRecursiveCall;
|
|
flattenedArray.push(lineItem);
|
|
if (lineItem.childParts) {
|
|
flattenedArray = [
|
|
...flattenedArray,
|
|
...getFlattenedArrayOfLineItemsWithChildParts(lineItem.childParts, true),
|
|
];
|
|
}
|
|
});
|
|
|
|
return flattenedArray;
|
|
}
|
|
|
|
function getFlattenedLineItemsWithGlassPartTag(lineItems) {
|
|
const nonGlassLineItems = [...(lineItems.supportingItems ?? []), ...(lineItems.vaps ?? [])];
|
|
const mappedNonGlassLineItems = nonGlassLineItems.map((lineItem) => {
|
|
return {
|
|
partNumber: lineItem.partNumber,
|
|
partType: lineItem.partType,
|
|
isGlassPart: false,
|
|
};
|
|
});
|
|
|
|
const glassLineItems = [...getFlattenedArrayOfLineItemsWithChildParts(lineItems.glassParts)];
|
|
const mappedGlassLineItems = glassLineItems.map((lineItem) => {
|
|
return {
|
|
partNumber: lineItem.partNumber,
|
|
partType: lineItem.partType,
|
|
isGlassPart: lineItem.isChildPart ? false : true,
|
|
};
|
|
});
|
|
|
|
return [...mappedNonGlassLineItems, ...mappedGlassLineItems];
|
|
}
|
|
|
|
function buildQueryStringParameterFromArrayOfComplexObjects(arrayOfObjects, parameterName) {
|
|
let queryStringParameter = "";
|
|
for (let i = 0; i < arrayOfObjects.length; i++) {
|
|
for (const [key, value] of Object.entries(arrayOfObjects[i])) {
|
|
if (value || value === 0) {
|
|
queryStringParameter += `${parameterName}[${i}].${key}=${value}&`;
|
|
}
|
|
}
|
|
}
|
|
// Remove trailing &
|
|
return queryStringParameter.slice(0, -1);
|
|
}
|
|
|
|
function convertGlassPieceToBackEndCompatibleFormat(glassPieces) {
|
|
return glassPieces.map((glassPiece) => {
|
|
return {
|
|
location: glassPiece.glassLocation,
|
|
name: glassPiece.glassName,
|
|
};
|
|
});
|
|
}
|
|
|
|
function renameGlassToReplaceAttributes(glassToReplace) {
|
|
let newGlassToReplace = [];
|
|
if (glassToReplace) {
|
|
newGlassToReplace = glassToReplace.map((item) => {
|
|
return { location: item.glassLocation, name: item.glassName };
|
|
});
|
|
}
|
|
return newGlassToReplace;
|
|
}
|
|
|
|
function addGuidToLineItemsIfNotAlreadyThere(lineItems) {
|
|
lineItems?.forEach((lineItem) => {
|
|
if (!lineItem.id) {
|
|
lineItem.id = crypto.randomUUID();
|
|
}
|
|
if (lineItem.childParts) {
|
|
addGuidToLineItemsIfNotAlreadyThere(lineItem.childParts);
|
|
}
|
|
});
|
|
}
|
|
|
|
function syncLineItemIds(lineItemsWithoutIds, lineItemsWithIds) {
|
|
if (!lineItemsWithIds || !lineItemsWithoutIds) {
|
|
return;
|
|
}
|
|
var clonedLineItemsWithIds = deepClone(lineItemsWithIds);
|
|
lineItemsWithoutIds.forEach((noId) => {
|
|
var matchedLineItemIndex = -1;
|
|
clonedLineItemsWithIds.forEach((withId, index) => {
|
|
if (noId.partNumber === withId.partNumber && noId.partType === withId.partType) {
|
|
matchedLineItemIndex = index;
|
|
noId.id = withId.id;
|
|
}
|
|
});
|
|
if (matchedLineItemIndex > -1) {
|
|
// Remove the matched line item
|
|
clonedLineItemsWithIds.splice(matchedLineItemIndex, 1);
|
|
}
|
|
});
|
|
}
|
|
|
|
function providersEqual(providerA, providerB) {
|
|
return (
|
|
providerA.providerNumber === providerB.providerNumber &&
|
|
providerA.address?.city === providerB.address?.city &&
|
|
providerA.address?.state === providerB.address?.state &&
|
|
providerA.address?.streetAddress === providerB.address?.streetAddress &&
|
|
providerA.address?.zipCode === providerB.address?.zipCode
|
|
);
|
|
//TODO: Change back to deepEqual once zipCodeCtu is added to saveSession.
|
|
}
|
|
|
|
function supportingItemsEqual(supportingItemsA, supportingItemsB) {
|
|
if (typeof supportingItemsA !== typeof supportingItemsB) {
|
|
return false;
|
|
}
|
|
if (supportingItemsA === null || supportingItemsB === null) {
|
|
return supportingItemsA === supportingItemsB;
|
|
}
|
|
if (supportingItemsA.length != supportingItemsB.length) {
|
|
return false;
|
|
}
|
|
const sortedA = supportingItemsA.slice().sort();
|
|
const sortedB = supportingItemsB.slice().sort();
|
|
for (let i = 0; i < sortedA.length; i++) {
|
|
if (
|
|
sortedA[i].partNumber != sortedB[i].partNumber ||
|
|
sortedA[i].partType != sortedB[i].partType
|
|
) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// This function will verify schedule info is still valid.
|
|
// check to see if we have an appointment date on the order object.
|
|
// if so, make sure it's not in the past. if in the past, clear schedule info in store.
|
|
// if date not in past, then call schedule service to verify appointment is still available.
|
|
async function resetScheduleIfUnavailable(context, order, pageNameToLog) {
|
|
// lineItems empty can happen when a customer goes all the way through scheduling as cash but then
|
|
// switches to insurance AND also switches vehicles during policy lookup. If you call shop-time-slots
|
|
// without parts, you get 500 errors so skip the call.
|
|
const lineItems = getArrayOfAllLineItemsAndChildParts(order.lineItems);
|
|
|
|
if (!order.schedule?.date || lineItems.length === 0) {
|
|
console.log(new Date() + " no schedule date or lineItems. skip resetSchedule logic.");
|
|
console.log(new Date() + " schedule.schedule.date" + JSON.stringify(order.schedule));
|
|
console.log(new Date() + " lineItems" + JSON.stringify(order.lineItems));
|
|
return;
|
|
}
|
|
|
|
// Date string with slashes is parsed as local time, not UTC. Our date has dashes, '-'.
|
|
// If you put any kind of time stamp on the date string with dashes, then it IS parsed as local time.
|
|
var aptDate = new Date(order.schedule.date + "T00:00:00");
|
|
var curDate = new Date();
|
|
curDate.setHours(0, 0, 0, 0);
|
|
|
|
// if appointment date is in the past, clear schedule
|
|
if (aptDate.getTime() < curDate.getTime()) {
|
|
context.commit(storeMutations.RESET_SCHEDULE);
|
|
return;
|
|
}
|
|
|
|
// create date range to pass to the schedule service to see if our appointment is still available.
|
|
var endRange = new Date(aptDate);
|
|
endRange.setDate(aptDate.getDate() + 1);
|
|
|
|
var endDay = "" + endRange.getDate();
|
|
var endMonth = "" + (endRange.getMonth() + 1); // 0 based so add 1
|
|
const endYear = endRange.getFullYear();
|
|
|
|
if (endMonth.length < 2) {
|
|
endMonth = "0" + endMonth;
|
|
}
|
|
if (endDay.length < 2) {
|
|
endDay = "0" + endDay;
|
|
}
|
|
|
|
const endDate = [endYear, endMonth, endDay].join("-");
|
|
|
|
let newTimeSlotsResponse;
|
|
if (order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE) {
|
|
newTimeSlotsResponse = await context.dispatch(
|
|
storeActions.GET_MOBILE_TIME_SLOTS,
|
|
{
|
|
payload: {
|
|
startDate: order.schedule.date,
|
|
endDate: endDate,
|
|
},
|
|
pageNameToLog: pageNameToLog,
|
|
},
|
|
false
|
|
);
|
|
|
|
if (newTimeSlotsResponse?.data.days?.length === 0) {
|
|
context.commit(storeMutations.RESET_SCHEDULE);
|
|
return;
|
|
}
|
|
|
|
var mobileRouteCodeFound = false;
|
|
// if early bird fee is in supporting items then need to check the timeslot to see if offer premium is also still available
|
|
if (
|
|
order.lineItem?.supportingItems?.findIndex(
|
|
(item) => item.partType == PREMIUM_FEE_PART_TYPE
|
|
)
|
|
) {
|
|
newTimeSlotsResponse.data.days?.forEach((day) => {
|
|
day.timeSlots.forEach((ts) => {
|
|
if (ts.id === order.schedule.routeCode && ts.offerPremium) {
|
|
mobileRouteCodeFound = true;
|
|
}
|
|
});
|
|
});
|
|
} else {
|
|
newTimeSlotsResponse.data.days?.forEach((day) => {
|
|
day.timeSlots.forEach((ts) => {
|
|
if (ts.id === order.schedule.routeCode) {
|
|
mobileRouteCodeFound = true;
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
if (!mobileRouteCodeFound) {
|
|
context.commit(storeMutations.RESET_SCHEDULE);
|
|
return;
|
|
}
|
|
} else {
|
|
newTimeSlotsResponse = await context.dispatch(
|
|
storeActions.GET_SHOP_TIME_SLOTS,
|
|
{
|
|
payload: {
|
|
startDate: order.schedule.date,
|
|
endDate: endDate,
|
|
shopAppointmentType: order.serviceLocation.appointmentType,
|
|
providerNumber: order.serviceLocation.provider.providerNumber,
|
|
},
|
|
pageNameToLog: pageNameToLog,
|
|
},
|
|
false
|
|
);
|
|
|
|
if (newTimeSlotsResponse?.data.days?.length === 0) {
|
|
context.commit(storeMutations.RESET_SCHEDULE);
|
|
return;
|
|
}
|
|
|
|
var routeCodeFound = false;
|
|
newTimeSlotsResponse.data.days?.forEach((day) => {
|
|
day.timeSlots.forEach((ts) => {
|
|
if (ts.id === order.schedule.routeCode) {
|
|
routeCodeFound = true;
|
|
}
|
|
});
|
|
});
|
|
|
|
//reset schedule if jobMin is null because when switching from cash to insurance dynamo returns null for jobMin
|
|
if (!routeCodeFound || order.schedule.jobMinMinutes == null) {
|
|
context.commit(storeMutations.RESET_SCHEDULE);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
function createExternalParameterDefaultState() {
|
|
// create default externalParameter state
|
|
const externalParameterDefaultState = {
|
|
isExternalParameter: externalParameterStatus.NOT_SET,
|
|
qsStash: null,
|
|
vehicle: {
|
|
year: null,
|
|
make: null,
|
|
model: null,
|
|
style: null,
|
|
},
|
|
vehicleDamage: {
|
|
damageType: null,
|
|
isRepair: null,
|
|
numberOfChips: null,
|
|
},
|
|
estimate: {
|
|
vinSelection: null,
|
|
},
|
|
serviceZip: {
|
|
zipCode: null,
|
|
},
|
|
quote: {
|
|
isInsurance: null,
|
|
servicePackage: null,
|
|
},
|
|
customer: {
|
|
emailAddress: null,
|
|
phoneNumber: null,
|
|
},
|
|
};
|
|
// set to session storage
|
|
saveExternalParameterState(externalParameterDefaultState);
|
|
}
|
|
function getExternalParameterDefaultState() {
|
|
const externalParameterState = window.sessionStorage.getItem(
|
|
sessionStorageKeyConstants.EXTERNAL_PARAMETER_STATE
|
|
);
|
|
if (externalParameterState === null) {
|
|
createExternalParameterDefaultState();
|
|
}
|
|
return JSON.parse(
|
|
window.sessionStorage.getItem(sessionStorageKeyConstants.EXTERNAL_PARAMETER_STATE)
|
|
);
|
|
}
|
|
function saveExternalParameterState(externalParameterState) {
|
|
window.sessionStorage.setItem(
|
|
sessionStorageKeyConstants.EXTERNAL_PARAMETER_STATE,
|
|
JSON.stringify(externalParameterState)
|
|
);
|
|
}
|
|
|
|
const timeSlotCallFlags = {
|
|
shop: false,
|
|
mobile: false,
|
|
shopV2: false,
|
|
mobileV2: false,
|
|
};
|
|
|
|
function checkIfMiscParts(partsOrQuestions) {
|
|
if (!partsOrQuestions || partsOrQuestions.length === 0) {
|
|
return { PartsNotFound: true };
|
|
} else if (
|
|
partsOrQuestions.length === 1 &&
|
|
partsOrQuestions[0].parts &&
|
|
partsOrQuestions[0].parts.length === 1 &&
|
|
partsOrQuestions[0].parts[0].partNumber.startsWith("MISC")
|
|
) {
|
|
return { PartsNotFound: true };
|
|
}
|
|
return { PartsNotFound: false };
|
|
}
|