3290 lines
147 KiB
JavaScript
3290 lines
147 KiB
JavaScript
import { defineStore } from 'pinia';
|
|
import applicationConfig from '@/constants/application-config';
|
|
import bailoutCode from '@/constants/bailoutCode';
|
|
import coverageStatuses from '@/constants/coverage-statuses';
|
|
import coverageType from '@/constants/coverage-type';
|
|
import damageLocationsSelected from '@/constants/damage-locations-selected';
|
|
import endorsementOptions from '@/constants/endorsement-options';
|
|
import endpoints from '@/constants/endpoints';
|
|
import { experimentSettings, experimentTriggers, experimentUniverses } from '@/constants/experiments';
|
|
import partNumberStrings from '@/constants/part-number-strings';
|
|
import partTypeStrings from '@/constants/part-type-strings';
|
|
import { paymentMethods } from '@/constants/payment-method-constants';
|
|
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
|
|
import webStorageConstants from '@/constants/web-storage-constants';
|
|
import globalMethods from '@/global-methods';
|
|
import { getSessionKeyValue, getUserIdValue, deleteISSCookie, getDeviceIdValue } from '@/helpers/cookie-helper';
|
|
import { convertDateStringToDate, getDateDifferenceInDays, militaryToTwelveHourTime } from '@/helpers/date-helper';
|
|
import { getExperimentSettingValue, getFeatureTogglesPayloadObject } from '@/helpers/experiment-helper';
|
|
import { findLineItemIndex, getLineItemsFlattened } from '@/helpers/line-items-helper';
|
|
import {
|
|
deductibleForSelectedVehicle, endorsementsForSelectedVehicle, endorsementCodesForSelectedVehicle,
|
|
noCoverageForSelectedVehicle,
|
|
repairWaivedForSelectedVehicle
|
|
} from '@/helpers/policy-vehicle-helper';
|
|
import { buildURLSearchParams, getPartNumbersListForQueryString } from '@/helpers/querystring-helper';
|
|
import { getRecalPartNumbers, getTopLevelGlassPartsWithRecal, getHasRecalibrationPart } from '@/helpers/recal-helper';
|
|
import { getDateForSavedSessionTimeout } from '@/helpers/session-helper';
|
|
import { isMobileDevice } from '@/helpers/useragent-helper';
|
|
import issPageValues from '@/router/router-constants/issPage-values';
|
|
import CoverageStatuses from '@/constants/coverage-statuses';
|
|
import { getNonFalseValuesOfPropertyInArrayOfObjects, sortArrayOfObjectsByPropertyValue } from '@/helpers/object-helper';
|
|
|
|
const storeId = 'main';
|
|
|
|
function getDisplayTextForDurationLength(durationMinimum, durationMaximum) {
|
|
const isLongAppointment = durationMaximum >= 120;
|
|
const isDurationRange = durationMinimum !== durationMaximum;
|
|
|
|
const adjustedMinimum = isLongAppointment ? durationMinimum / 60 : durationMinimum;
|
|
const adjustedMaximum = isLongAppointment ? durationMaximum / 60 : durationMaximum;
|
|
|
|
const durationText = isDurationRange
|
|
? `${adjustedMinimum} - ${adjustedMaximum}`
|
|
: adjustedMinimum;
|
|
|
|
const unitText = isLongAppointment ? 'hours' : 'minutes';
|
|
|
|
return `${durationText} ${unitText}`;
|
|
}
|
|
|
|
function getTimeSlotsAdditionalEventData(
|
|
provisionalTriggers,
|
|
zipCode,
|
|
firstAvailableAppointmentDateString,
|
|
shopAppointmentType
|
|
) {
|
|
let numberOfDays = null;
|
|
if (firstAvailableAppointmentDateString) numberOfDays = getDateDifferenceInDays(new Date(), firstAvailableAppointmentDateString);
|
|
|
|
if (shopAppointmentType) return `FirstAvailableAppointment:${numberOfDays},Zip:${zipCode},ShopAppointmentType:${shopAppointmentType},ProvisionalTriggers:${provisionalTriggers.join(',')}`;
|
|
return `FirstAvailableAppointment:${numberOfDays},Zip:${zipCode},ProvisionalTriggers:${provisionalTriggers.join(',')}`;
|
|
}
|
|
|
|
export const getDefaultState = () => ({
|
|
order: {
|
|
vehicle: {
|
|
policyVehicleId: null,
|
|
year: null,
|
|
make: null,
|
|
model: null,
|
|
style: null,
|
|
carId: null,
|
|
category: null,
|
|
vin: null,
|
|
imageUrl: null,
|
|
imageVifNumber: null,
|
|
imageColor: null,
|
|
registration: { // TODO only licensePlate saved in save session
|
|
licensePlate: null,
|
|
address: null,
|
|
city: null,
|
|
state: null,
|
|
zipCode: null,
|
|
firstName: null,
|
|
lastName: null
|
|
},
|
|
isBigTruck: null,
|
|
canSafeliteService: null
|
|
},
|
|
damage: {
|
|
isRepair: null,
|
|
numberOfChips: null,
|
|
glassToReplace: null,
|
|
partQuestionAnswers: null,
|
|
moldingQuestionAnswers: null,
|
|
capabilityQuestionAnswers: null
|
|
},
|
|
policy: {
|
|
policyNumber: null,
|
|
policyZipCode: null,
|
|
dateOfLoss: null,
|
|
damageCause: null,
|
|
damageState: null,
|
|
damageCity: null,
|
|
isDamageGlassOnly: null,
|
|
deductible: {
|
|
repair: null, // numerical value; how much customer owes on deductible in repair case
|
|
replace: null // numerical value; how much customer owes on deductible in replace case,
|
|
},
|
|
vehicles: [],
|
|
endorsements: [],
|
|
endorsementQuestionAnswers: [],
|
|
cvrgEndorsementCode: null,
|
|
status: null,
|
|
policyData: null,
|
|
policyLookupErrorCode: 0
|
|
},
|
|
customer: {
|
|
address: {
|
|
streetAddress: null,
|
|
streetAddress2: null,
|
|
city: null,
|
|
state: null,
|
|
zipCode: null
|
|
},
|
|
firstName: null,
|
|
lastName: null,
|
|
emailAddress: null
|
|
},
|
|
serviceLocation: {
|
|
address: null,
|
|
address2: null,
|
|
city: null,
|
|
state: null,
|
|
zipCode: null,
|
|
zipCodeCtu: null,
|
|
defaultProviderNumber: null,
|
|
appointmentType: null,
|
|
isVehicleProtected: null,
|
|
IsSafeliteProvider: null,
|
|
tpaSearchRadius: null,
|
|
provider: {
|
|
providerNumber: null,
|
|
address: {
|
|
streetAddress: null,
|
|
city: null,
|
|
state: null,
|
|
zipCode: null,
|
|
zipCodeCtu: null
|
|
},
|
|
companyName: null,
|
|
phoneNumber: null
|
|
}
|
|
},
|
|
lineItems: {
|
|
glassParts: null,
|
|
otherParts: null,
|
|
supportingItems: null,
|
|
feeItems: [],
|
|
vaps: null,
|
|
serverData: null
|
|
},
|
|
servicePackage: null,
|
|
insuranceCoverage: {
|
|
coverageStatus: coverageStatuses.PENDING,
|
|
coverageType: coverageType.NONE,
|
|
isItacOptimized: false,
|
|
claimNumber: null
|
|
},
|
|
payment: {
|
|
parentAccountNumber: 0,
|
|
nextGenSettledAmount: 0,
|
|
paymentMethod: null,
|
|
paypalToken: null,
|
|
creditCardToken: {
|
|
subscriptionId: null,
|
|
expMonth: null,
|
|
expYear: null,
|
|
cardType: null,
|
|
billToPostalCode: null,
|
|
billToFirstName: null,
|
|
billToLastName: null,
|
|
referenceNumber: null,
|
|
authCode: null,
|
|
transactionId: null,
|
|
transReferenceNumber: null,
|
|
lastFour: null
|
|
}
|
|
},
|
|
contactInfo: {
|
|
homePhone: null,
|
|
alternativePhone: null,
|
|
servicePhone: null,
|
|
extension: null,
|
|
requestTextUpdates: false,
|
|
notesForTechnician: ''
|
|
},
|
|
schedule: {
|
|
date: null,
|
|
startTime: null,
|
|
endTime: null,
|
|
routeCode: null,
|
|
jobMaxMinutes: null,
|
|
jobMinMinutes: null
|
|
},
|
|
parentAccountNumber: null,
|
|
referralNumber: null,
|
|
referralDate: null,
|
|
referralCorrelationId: '00000000-0000-0000-0000-000000000000',
|
|
referralSequenceNumber: null,
|
|
eon: null,
|
|
workOrderId: null,
|
|
workOrderNumber: null,
|
|
settledTenderAmount: null,
|
|
lockToken: null,
|
|
customerPortalLoginToken: null,
|
|
originalDeductible: {
|
|
repair: null,
|
|
replace: null
|
|
},
|
|
currentDeductible: {
|
|
repair: null,
|
|
replace: null
|
|
},
|
|
totalTaxAmount: null,
|
|
waiverReasons: null,
|
|
carrierPhoneNumber: null,
|
|
loadedFromCookie: false,
|
|
loadedFromDupeCheck: null,
|
|
loadedSessionClearedPreviousData: null,
|
|
availableVaps: null,
|
|
visitedDuplicateCheckPage: false,
|
|
isRecalAcknowledgedForScheduling: false
|
|
},
|
|
applicationUser: {
|
|
experiments: [],
|
|
eventBus: [], // TODO not in save session
|
|
pageData: {},
|
|
savedSessionTimeout: getDateForSavedSessionTimeout(),
|
|
saveSessionPromise: null,
|
|
savedSessionId: '00000000-0000-0000-0000-000000000000',
|
|
crmCustomerId: null,
|
|
lastPageVisited: null,
|
|
triggeredSiteEntry: false, // TODO not in save session
|
|
duplicateOrders: [],
|
|
hasSentSaveQuoteEmail: null,
|
|
coverageLookupAttempts: 0,
|
|
//logErrorCalls: 0,
|
|
firstHit: true
|
|
},
|
|
issConfig: {
|
|
clientName: 'Generic Insurance', // this is the default and will be overriden by the client's name
|
|
clientFullName: 'Generic Insurance', // this is the default and will be overriden by the client's name or client's full name.
|
|
clientDisplayName: 'Generic Insurance', // this is the default and will be overridden by the client's name or client display name.
|
|
clientPossessiveName: 'Generic Insurance\'s', // this is the default and will be overridden by the client's name or client display name converted to possessive or the clients possessive name.
|
|
clientHeader: {},
|
|
styleSheet: '', // Stylesheet used by the client.
|
|
parentAccountNumber: 0, // Parent account number used by the client.
|
|
billToAccountNumber: null,
|
|
isCoverageEnabled: false, // Indicates if we should be calling coverage on this flow.
|
|
isClaimRegistrationRequired: false, // Indicates if the claim registration call needs to be made for a client to complete coverage verification.
|
|
isAuthenticated: false, // Indicates if user is authenticated or not.
|
|
enableContinueFromCookie: false, // Indicates if the continue from cookie modal should appear.
|
|
enableTPAFlow: false, // Indicates if the TPA flow is supported for this client.
|
|
successReturnURL: null, // Client URL to return the user to upon a successfull flow completetion (order submission).
|
|
failureReturnURL: null, // Client URL to return the user to when they encounter an error or bailout and are unable to complete the flow.
|
|
disabledFields: { // Fields that are disabled and read only if sent over from a client.
|
|
policyNumber: null,
|
|
policyZipCode: null,
|
|
dateOfLoss: null
|
|
},
|
|
siteType: null,
|
|
enableNoCompQuote: false
|
|
}
|
|
});
|
|
|
|
export const state = getDefaultState();
|
|
|
|
export const useMainStore = defineStore({
|
|
id: storeId,
|
|
state: () => state,
|
|
getters: {
|
|
billToAccountNumber: (storeState) => storeState.issConfig.billToAccountNumber,
|
|
hasRecalibrationPart: (storeState) => getHasRecalibrationPartOnOrder(storeState),
|
|
vehicle: (storeState) => storeState.order.vehicle,
|
|
damage: (storeState) => storeState.order.damage,
|
|
lineItems: (state) => state.order.lineItems,
|
|
payment: (state) => state.order.payment,
|
|
policy: (state) => state.order.policy,
|
|
serviceLocation: (state) => state.order.serviceLocation,
|
|
hasExactlyOneChip: () => state.order.damage.numberOfChips === 1,
|
|
isPolicyVehicle: () => state.order.vehicle.policyVehicleId != null,
|
|
hasWindshieldReplacement: (s) => {
|
|
const { damage, lineItems } = s.order;
|
|
return !damage.isRepair
|
|
&& (lineItems.glassParts?.some((gp) => gp.partType === partTypeStrings.WINDSHIELD) ?? false);
|
|
},
|
|
hasAnyNonWindshieldGlassParts: (s) => {
|
|
const { damage } = s.order;
|
|
const nonWindshieldItems = damage.glassToReplace?.filter((glass) => glass.glassLocation !== damageLocationsSelected.WINDSHIELD);
|
|
return !!nonWindshieldItems?.length;
|
|
},
|
|
hasMoldingPart: (s) => {
|
|
return s.order.lineItems.glassParts?.some((glassPart) => {
|
|
return glassPart.childParts?.some((childPart) => childPart.partType === partTypeStrings.MOLDING);
|
|
});
|
|
},
|
|
isMobileAppointment: (state) => state.order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE
|
|
|| state.order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP,
|
|
isDropOffAppointment: (state) => state.order.serviceLocation.appointmentType === AppointmentTypeStrings.DROP_OFF,
|
|
isInShopAppointment: (state) => state.order.serviceLocation.appointmentType === AppointmentTypeStrings.IN_SHOP,
|
|
isClaimRegistrationRequired: (state) => state.issConfig.isClaimRegistrationRequired,
|
|
isClaimAlreadyRegistered: (state) => state.order.insuranceCoverage.claimNumber !== null,
|
|
isBailout: (state) => state.applicationUser.pageData[issPageValues.BAILOUT_PAGE] != null,
|
|
bailoutCode: (state) => state.applicationUser.pageData[issPageValues.BAILOUT_PAGE]?.bailoutCode,
|
|
isPolicyLookupSuccessful: (s) => s.order.insuranceCoverage.coverageType !== coverageType.NONE,
|
|
isNoComp: (s) => s.order.insuranceCoverage.coverageType === coverageType.NO_COMP,
|
|
isNoCompQuoteEnabled: (s) => s.issConfig.enableNoCompQuote,
|
|
isITAC: (state) => state.order.insuranceCoverage.coverageType === coverageType.ITAC,
|
|
isDeductible: (state) => state.order.insuranceCoverage.coverageType === coverageType.Deductible,
|
|
isUnverified: (s) => s.order.insuranceCoverage.coverageStatus !== coverageStatuses.VERIFIED,
|
|
isVerified: (state) => state.order.insuranceCoverage.coverageStatus === coverageStatuses.VERIFIED,
|
|
isPendingClaimRegistration: (state) => state.order.insuranceCoverage.coverageStatus === coverageStatuses.PENDING,
|
|
isPayInAdvance: (state) => state.order.payment.paymentMethod != null && state.order.payment.paymentMethod !== paymentMethods.PAY_AT_TIME_OF_SERVICE,
|
|
providerNumber: (state) => state.order.serviceLocation.provider.providerNumber || state.order.serviceLocation.defaultProviderNumber,
|
|
hasOemEndorsement: (state) => state.order.policy.endorsements?.indexOf('OEM Approved') !== -1 ?? false,
|
|
eventBusItem: (state) => (eventCategory, eventSubCategory) => {
|
|
const matchedEvent = state.applicationUser.eventBus.find(({ category, subCategory }) => category === eventCategory && subCategory === eventSubCategory);
|
|
return matchedEvent?.eventValue;
|
|
},
|
|
eventBus: (state) => state.applicationUser.eventBus,
|
|
applicationUserObj: (state) => state.applicationUser,
|
|
pageData: (state) => (page) => (page in state.applicationUser.pageData
|
|
? state.applicationUser.pageData[page]
|
|
: undefined),
|
|
customerData: (state) => {
|
|
if (state.order.vehicle.registration.address) {
|
|
const { registration } = state.order.vehicle;
|
|
return {
|
|
addressQuestions: {
|
|
streetAddress: registration.address,
|
|
city: registration.city,
|
|
state: registration.state,
|
|
zipCode: registration.zipCode
|
|
},
|
|
firstName: registration.firstName,
|
|
lastName: registration.lastName
|
|
};
|
|
}
|
|
|
|
const { address } = state.order.customer;
|
|
return {
|
|
addressQuestions: {
|
|
streetAddress: address.streetAddress,
|
|
city: address.city,
|
|
state: address.state,
|
|
zipCode: address.zipCode
|
|
},
|
|
firstName: state.order.customer.firstName,
|
|
lastName: state.order.customer.lastName
|
|
};
|
|
},
|
|
contactInfo: (s) => ({
|
|
firstName: s.order.customer.firstName,
|
|
lastName: s.order.customer.lastName,
|
|
emailAddress: s.order.customer.emailAddress,
|
|
homePhone: s.order.contactInfo.homePhone,
|
|
alternativePhone: s.order.contactInfo.alternativePhone,
|
|
servicePhone: s.order.contactInfo.servicePhone,
|
|
extension: s.order.contactInfo.extension,
|
|
requestTextUpdates: s.order.contactInfo.requestTextUpdates ?? false,
|
|
notesForTechnician: s.order.contactInfo.notesForTechnician
|
|
}),
|
|
scheduleDisplayText: (s) => {
|
|
const dateModel = convertDateStringToDate(s.order.schedule.date);
|
|
const readableDate = dateModel?.toLocaleDateString('en-us', {
|
|
weekday: 'long',
|
|
month: 'long',
|
|
day: 'numeric',
|
|
year: 'numeric'
|
|
});
|
|
|
|
const readableStartTime = militaryToTwelveHourTime(s.order.schedule.startTime);
|
|
const readableEndTime = militaryToTwelveHourTime(s.order.schedule.endTime);
|
|
|
|
const readableDuration = getDisplayTextForDurationLength(
|
|
s.order.schedule.jobMinMinutes,
|
|
s.order.schedule.jobMaxMinutes
|
|
);
|
|
|
|
return {
|
|
date: readableDate,
|
|
startTime: readableStartTime,
|
|
endTime: readableEndTime,
|
|
duration: readableDuration
|
|
};
|
|
},
|
|
experimentOrder: (s) => {
|
|
const ctuToUse = (s.order.serviceLocation.appointmentType === AppointmentTypeStrings.IN_SHOP
|
|
|| s.order.serviceLocation.appointmentType === AppointmentTypeStrings.DROP_OFF)
|
|
? s.order.serviceLocation.provider?.address?.zipCodeCtu : s.order.serviceLocation.zipCodeCtu;
|
|
|
|
return {
|
|
funnelVehicleYear: s.order.vehicle.year,
|
|
funnelVehicleMake: s.order.vehicle.make,
|
|
funnelVehicleModel: s.order.vehicle.model,
|
|
funnelVehicleStyle: s.order.vehicle.style,
|
|
funnelIsRepair: s.order.damage.isRepair,
|
|
funnelNumberOfChips: s.order.damage.numberOfChips,
|
|
funnelCarId: s.order.vehicle.carId,
|
|
funnelServiceCity: s.order.serviceLocation.city,
|
|
funnelServices: s.order.serviceLocation.state,
|
|
funnelServiceZipCode: s.order.serviceLocation.zipCode,
|
|
funnelServiceZipCodeCtu: ctuToUse,
|
|
funnelParentAccountNumber: s.order.parentAccountNumber,
|
|
funnelProviderNumber: s.providerNumber,
|
|
funnelIsCoverageVerified: s.isVerified,
|
|
funnelHasRecalibrationPart: getHasRecalibrationPart(s),
|
|
funnelSelectedMultiGlass: s.order.damage.glassToReplace?.length > 1,
|
|
funnelSelectedWindshieldGlass: getNonFalseValuesOfPropertyInArrayOfObjects(s.order.damage.glassToReplace, 'glassLocation')
|
|
.includes(damageLocationsSelected.WINDSHIELD),
|
|
funnelSelectedBackGlass: getNonFalseValuesOfPropertyInArrayOfObjects(s.order.damage.glassToReplace, 'glassLocation')
|
|
.includes(damageLocationsSelected.REAR),
|
|
funnelSelectedDriverSideGlass: getNonFalseValuesOfPropertyInArrayOfObjects(s.order.damage.glassToReplace, 'glassLocation')
|
|
.includes(damageLocationsSelected.DRIVER),
|
|
funnelSelectedPassengerSideGlass: getNonFalseValuesOfPropertyInArrayOfObjects(s.order.damage.glassToReplace, 'glassLocation')
|
|
.includes(damageLocationsSelected.PASSENGER),
|
|
funnelOrderPartNumbers: [
|
|
...getNonFalseValuesOfPropertyInArrayOfObjects(
|
|
s.order.lineItems.glassParts,
|
|
'partNumber'
|
|
),
|
|
...getNonFalseValuesOfPropertyInArrayOfObjects(
|
|
s.order.lineItems.otherParts,
|
|
'partNumber'
|
|
)
|
|
],
|
|
funnelOrderPartTypes: [
|
|
...getNonFalseValuesOfPropertyInArrayOfObjects(
|
|
s.order.lineItems.glassParts,
|
|
'recalibrationType'
|
|
),
|
|
...getNonFalseValuesOfPropertyInArrayOfObjects(
|
|
s.order.lineItems.otherParts,
|
|
'recalibrationType'
|
|
)
|
|
]
|
|
};
|
|
},
|
|
experimentSettings: (state) => state.applicationUser.experiments
|
|
.filter((x) => !!x.isActive)
|
|
.map((x) => x.settings)
|
|
.reduce((r, c) => Object.assign(r, c), {}) ?? {},
|
|
originalDeductible: (state) => (state.order.damage.isRepair ? state.order.originalDeductible.repair : state.order.originalDeductible.replace),
|
|
currentDeductible: (state) => (state.order.damage.isRepair ? state.order.currentDeductible.repair : state.order.currentDeductible.replace),
|
|
accountNameForEvents: (state) => state.issConfig.clientName
|
|
},
|
|
actions:
|
|
{
|
|
// Content API Actions
|
|
|
|
lookupVinByAddress({ licenseLastName, licenseStreetAddress, licenseZip, licenseState }) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LookupVinByAddress.method,
|
|
endpoint: endpoints.LookupVinByAddress.url,
|
|
payload: {
|
|
licenseLastName,
|
|
licenseStreetAddress,
|
|
licenseZip,
|
|
licenseState
|
|
}
|
|
});
|
|
},
|
|
|
|
getRouteInfo(pageName) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetRouteInfo.method,
|
|
endpoint: endpoints.GetRouteInfo.url(applicationConfig.APPLICATION_ABBREVIATION),
|
|
payload: {
|
|
pageName
|
|
}
|
|
});
|
|
},
|
|
getHomepageName() {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetHomepageInfo.method,
|
|
endpoint: endpoints.GetHomepageInfo.url(applicationConfig.APPLICATION_ABBREVIATION)
|
|
});
|
|
},
|
|
|
|
getPageData(pageName) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetPageData.method,
|
|
endpoint: endpoints.GetPageData.url(applicationConfig.APPLICATION_ABBREVIATION, pageName),
|
|
payload: {}
|
|
});
|
|
},
|
|
|
|
// Vehicle API Actions
|
|
getVehicleYears() {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetVehicleYears.method,
|
|
endpoint: endpoints.GetVehicleYears.url,
|
|
payload: {}
|
|
});
|
|
},
|
|
|
|
getVehicleMakes() {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetVehicleMakes.method,
|
|
endpoint: endpoints.GetVehicleMakes.url + this.order.vehicle.year,
|
|
payload: {}
|
|
});
|
|
},
|
|
|
|
getVehicleModels() {
|
|
const encodedMake = encodeURIComponent(this.order.vehicle.make);
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetVehicleModels.method,
|
|
endpoint: `${endpoints.GetVehicleModels.url}/${this.order.vehicle.year}/${encodedMake}`,
|
|
payload: {}
|
|
});
|
|
},
|
|
|
|
getVehicleStyles() {
|
|
const encodedMake = encodeURIComponent(this.order.vehicle.make);
|
|
const encodedModel = encodeURIComponent(this.order.vehicle.model);
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetVehicleStyles.method,
|
|
endpoint: `${endpoints.GetVehicleStyles.url}/${this.order.vehicle.year}/${encodedMake}/${encodedModel}`,
|
|
payload: {}
|
|
});
|
|
},
|
|
|
|
getDamageOptions(carId) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetDamageOptions.method,
|
|
endpoint: `${endpoints.GetDamageOptions.url}/${carId}`,
|
|
payload: {}
|
|
});
|
|
},
|
|
async getIsVinbyAddressPermissible() {
|
|
try {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.IsVinbyAddressPermissible.method,
|
|
endpoint: `${endpoints.IsVinbyAddressPermissible.url}?state=${this.order.customer.address.state}`,
|
|
payload: {}
|
|
});
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
},
|
|
async getCoveragePolicyInfo() {
|
|
const { order, issConfig, applicationUser } = this;
|
|
const { policy } = order;
|
|
|
|
if (!issConfig.isCoverageEnabled || applicationUser.coverageLookupAttempts > 10) {
|
|
this.updateCoverageType(coverageType.NONE);
|
|
return;
|
|
}
|
|
|
|
this.applicationUser.coverageAttempts += 1;
|
|
console.log(`Coverage lookup attempt #${this.applicationUser.coverageAttempts}. Max attempts allowed: 10.`);
|
|
|
|
try {
|
|
order.policy.policyLookupErrorCode = 0;
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.CoveragePolicyInfo.method,
|
|
endpoint: endpoints.CoveragePolicyInfo.url,
|
|
payload: {
|
|
accountNumber: order.parentAccountNumber?.toString(),
|
|
policyNumber: policy.policyNumber,
|
|
dateOfLoss: policy.dateOfLoss,
|
|
zipCode: policy.policyZipCode,
|
|
referralCorrelationId: order.referralCorrelationId
|
|
},
|
|
bailoutOnError: false
|
|
});
|
|
|
|
const responsePolicy = response?.data?.policies?.[0];
|
|
if (responsePolicy) {
|
|
this.updateCoverageType(coverageType.Deductible);
|
|
const insured = responsePolicy.insureds?.[0];
|
|
|
|
// populate parent account number
|
|
if (response.data.accountNumber) {
|
|
order.parentAccountNumber = parseInt(response.data.accountNumber, 10);
|
|
}
|
|
|
|
// populate policy holder details from policy lookup
|
|
order.customer.address.streetAddress = insured?.address;
|
|
order.customer.address.city = insured?.city;
|
|
order.customer.address.state = insured?.state;
|
|
order.customer.address.zipCode = insured?.zipCode?.toString();
|
|
order.customer.firstName = insured?.firstName;
|
|
order.customer.lastName = insured?.lastName;
|
|
|
|
// populate additional fields
|
|
order.policy.policyData = responsePolicy.policyData;
|
|
|
|
// populate vehicles
|
|
order.policy.vehicles = responsePolicy.vehicles ?? [];
|
|
} else {
|
|
if ( response?.data?.isError) {
|
|
order.policy.policyLookupErrorCode = response?.data?.errorCode;
|
|
}
|
|
this.updateCoverageType(coverageType.NONE);
|
|
}
|
|
} catch (e) {
|
|
this.updateCoverageType(coverageType.NONE);
|
|
}
|
|
},
|
|
clearDuplicateOrders() {
|
|
this.applicationUser.duplicateOrders = [];
|
|
},
|
|
updateDuplicateCheckVisited(visited) {
|
|
this.order.visitedDuplicateCheckPage = visited;
|
|
},
|
|
updateCoverageStatus(status) {
|
|
this.order.insuranceCoverage.coverageStatus = status;
|
|
},
|
|
updateCoverageType(type) {
|
|
this.order.insuranceCoverage.coverageType = type;
|
|
},
|
|
updateIsItacOptimized(isItacOptimized) {
|
|
this.order.insuranceCoverage.isItacOptimized = isItacOptimized || false;
|
|
},
|
|
async registerClaim() {
|
|
const nonNumberCharRegex = /[^0-9]/g;
|
|
const { isITAC } = this;
|
|
|
|
try {
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.RegisterClaim.method,
|
|
endpoint: endpoints.RegisterClaim.url,
|
|
payload:
|
|
{
|
|
referralCorrelationId: this.order.referralCorrelationId,
|
|
accountNumber: this.order.parentAccountNumber?.toString() ?? '',
|
|
policyData: this.order.policy.policyData,
|
|
// TODO: Remove this isRepair flag from the payload after coverage service updates are deployed.
|
|
// This is here in case we have to deploy site for other fixes before coverage service gets updated.
|
|
isRepair: this.order.damage.isRepair,
|
|
isItac: isITAC,
|
|
insured: {
|
|
firstName: this.order.customer.firstName,
|
|
lastName: this.order.customer.lastName,
|
|
address: {
|
|
addressLine1: this.order.customer.address.streetAddress,
|
|
addressLine2: this.order.customer.address.streetAddress2,
|
|
city: this.order.customer.address.city,
|
|
state: this.order.customer.address.state,
|
|
zipCode: this.order.customer.address.zipCode,
|
|
country: 'US' // TODO set from store
|
|
},
|
|
homePhone: {
|
|
number: this.contactInfo.homePhone?.replaceAll(nonNumberCharRegex, '') ?? ''
|
|
}
|
|
},
|
|
driver: {
|
|
firstName: this.order.customer.firstName,
|
|
lastName: this.order.customer.lastName
|
|
},
|
|
caller: {
|
|
homePhone: {}
|
|
},
|
|
policyInfo: {
|
|
policyNumber: this.order.policy.policyNumber,
|
|
safelitePolicy: {
|
|
policies: []
|
|
},
|
|
actualDeductible: this.currentDeductible.toString() ?? '',
|
|
currentRepairDeductible: this.order.currentDeductible.repair,
|
|
currentReplaceDeductible: this.order.currentDeductible.replace,
|
|
},
|
|
lossInfo: {
|
|
dateOfLoss: this.order.policy.dateOfLoss,
|
|
isRepair: this.order.damage.isRepair,
|
|
location: {
|
|
city: this.order.policy.damageCity,
|
|
state: this.order.policy.damageState,
|
|
country: 'US' // TODO set from store
|
|
},
|
|
vehicle: {
|
|
id: this.order.vehicle.policyVehicleId?.toString() ?? '',
|
|
year: this.order.vehicle.year?.toString() ?? '',
|
|
make: this.order.vehicle.make,
|
|
model: this.order.vehicle.model,
|
|
vin: this.order.vehicle.vin
|
|
},
|
|
cause: this.order.policy.damageCause,
|
|
damageDescription: this.order.policy.damageCause
|
|
}
|
|
},
|
|
bailoutOnError: false
|
|
});
|
|
this.order.insuranceCoverage.claimNumber = response.data.claimNumber;
|
|
if (response.data.isSuccess) {
|
|
this.updateCoverageStatus(coverageStatuses.VERIFIED);
|
|
} else {
|
|
this.updateCoverageStatus(coverageStatuses.NO_COVERAGE);
|
|
}
|
|
} catch (e) {
|
|
this.updateCoverageStatus(coverageStatuses.NO_COVERAGE);
|
|
this.order.insuranceCoverage.claimNumber = null;
|
|
}
|
|
},
|
|
async getFinalDeductible() {
|
|
const endorsementAnswersForPayload = [];
|
|
const endorsementAnswers = this.order.policy.endorsementQuestionAnswers;
|
|
if (endorsementAnswers) {
|
|
endorsementAnswers.forEach((endorsement) => {
|
|
if (endorsement.selectedAnswer === 'Yes') {
|
|
endorsementAnswersForPayload.push(endorsement.endorsementName);
|
|
}
|
|
});
|
|
}
|
|
|
|
const manualGlassNamesArray = [];
|
|
const glassInformation = this.order.damage.glassToReplace;
|
|
glassInformation?.forEach((glassPiece) => {
|
|
manualGlassNamesArray.push(glassPiece?.glassLocation?.toUpperCase());
|
|
});
|
|
|
|
try {
|
|
const r = await globalMethods.callHttpClient({
|
|
method: endpoints.FinalDeductible.method,
|
|
endpoint: endpoints.FinalDeductible.url,
|
|
payload: {
|
|
referralCorrelationId: this.order.referralCorrelationId,
|
|
accountNumber: this.order.parentAccountNumber?.toString() ?? '',
|
|
endorsements: endorsementAnswersForPayload,
|
|
manualGlassNames: manualGlassNamesArray,
|
|
policyState: this.order.customer.address.state,
|
|
status: this.order.policy.status,
|
|
originalDeductible: this.originalDeductible,
|
|
currentDeductible: this.currentDeductible,
|
|
currentRepairDeductible: this.order.currentDeductible.repair,
|
|
currentReplaceDeductible: this.order.currentDeductible.replace,
|
|
noCoverage: false,
|
|
isRepair: this.order.damage.isRepair,
|
|
policyNumber: this.order.policy.policyNumber,
|
|
insuredFirstName: this.order.customer.firstName,
|
|
insuredLastName: this.order.customer.lastName,
|
|
insuredZipCode: this.order.customer.address.zipCode,
|
|
policyVehicleId: this.order.vehicle.policyVehicleId?.toString() ?? '',
|
|
vehicleVin: this.order.vehicle.vin,
|
|
policyData: this.order.policy.policyData,
|
|
isItac: this.isITAC
|
|
},
|
|
bailoutOnError: false
|
|
});
|
|
this.order.policy.policyData = r.data.policyData;
|
|
this.updateDeductible(r.data);
|
|
return r;
|
|
} catch (e) {
|
|
this.updateCoverageStatus(CoverageStatuses.PENDING);
|
|
}
|
|
},
|
|
|
|
async getDuplicateReferrals() {
|
|
const params = new URLSearchParams({
|
|
parentAccountNumber: this.order.parentAccountNumber,
|
|
customerPhoneNumber: this.order.contactInfo.servicePhone,
|
|
policyNumber: this.order.policy.policyNumber,
|
|
emailAddress: this.order.customer.emailAddress,
|
|
dateOfLoss: this.order.policy.dateOfLoss
|
|
});
|
|
|
|
try {
|
|
const duplicates = await globalMethods.callHttpClient({
|
|
method: endpoints.DuplicateSearch.method,
|
|
endpoint: `${endpoints.DuplicateSearch.url}?${params.toString()}`,
|
|
bailoutOnError: false
|
|
});
|
|
this.applicationUser.duplicateOrders = duplicates.data ?? [];
|
|
} catch (e) {
|
|
this.applicationUser.duplicateOrders = [];
|
|
}
|
|
},
|
|
async lookupVinByPlate(licensePlate, licenseState) {
|
|
try {
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.LookupVinByPlate.method,
|
|
endpoint: endpoints.LookupVinByPlate.url,
|
|
payload: {
|
|
licensePlate,
|
|
licenseState
|
|
}
|
|
});
|
|
|
|
return response;
|
|
} catch (responseError) {
|
|
return {
|
|
error: {
|
|
status: responseError.status
|
|
}
|
|
};
|
|
}
|
|
},
|
|
|
|
// PartsOrQuestions API Actions
|
|
async getPartsOrQuestions() {
|
|
this.resetPartsAndDependencies();
|
|
|
|
const { vehicle } = this;
|
|
const { damage } = this;
|
|
const { order } = this;
|
|
|
|
const { carId } = vehicle;
|
|
const glassArray = damage.glassToReplace;
|
|
const zipCode = vehicle.registration.zipCode ? vehicle.registration.zipCode : order.customer.address.zipCode;
|
|
const { vin } = vehicle;
|
|
|
|
// create a new array to avoid mutating state
|
|
const glassArrayForPayload = convertGlassPieceNamingForApi(glassArray);
|
|
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.GetPartsOrQuestions.method,
|
|
endpoint: endpoints.GetPartsOrQuestions.url,
|
|
payload: {
|
|
carId,
|
|
glassPieces: glassArrayForPayload,
|
|
zip: zipCode,
|
|
vin,
|
|
oemEndorsementFlag: this.hasOemEndorsement
|
|
}
|
|
});
|
|
|
|
// Flatten location and name properties
|
|
response.data.partsOrQuestions = convertGlassPieceNamingFromApi(response.data.partsOrQuestions);
|
|
|
|
return response;
|
|
},
|
|
|
|
async getParts() {
|
|
const { vehicle } = this.order;
|
|
const { damage } = this.order;
|
|
const { order } = this;
|
|
|
|
const { carId } = vehicle;
|
|
const glassArray = damage.glassToReplace;
|
|
const resultsArray = damage.partQuestionAnswers;
|
|
const zipCode = vehicle.registration.zipCode ? vehicle.registration.zipCode : order.customer.address.zipCode;
|
|
const { vin } = vehicle;
|
|
|
|
// 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,
|
|
glassPieces: glassArrayForPayload,
|
|
answerResults: resultsArrayForPayload,
|
|
zip: zipCode,
|
|
vin,
|
|
oemEndorsementFlag: this.hasOemEndorsement
|
|
}
|
|
});
|
|
|
|
// Flatten location and name properties
|
|
response.data.glassPieceParts = convertGlassPieceNamingFromApi(response.data.glassPieceParts);
|
|
|
|
return response;
|
|
},
|
|
|
|
getCapabilityQuestions(carId, partNumber) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetCapabilityQuestions.method,
|
|
endpoint: `${endpoints.GetCapabilityQuestions.url}/${carId}/${partNumber}`
|
|
});
|
|
},
|
|
|
|
async updatePartFromCapabilityQuestionAnswer(part, capabilityQuestionAnswersForPart) {
|
|
return (await globalMethods.callHttpClient({
|
|
method: endpoints.GetPartFromCapabilityAnswer.method,
|
|
endpoint: endpoints.GetPartFromCapabilityAnswer.url,
|
|
payload: {
|
|
part,
|
|
capabilityAnswerResults: capabilityQuestionAnswersForPart
|
|
}
|
|
})).data[0];
|
|
},
|
|
getMobilePremiumFee() {
|
|
const damageType = this.damage.isRepair ? 'Repair' : 'Replace';
|
|
const paymentType = 'Insurance';
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetMobilePremiumFee.method,
|
|
endpoint: `${endpoints.GetMobilePremiumFee.url}/${paymentType}/${damageType}`
|
|
});
|
|
},
|
|
getMobileTimeSlots(startDate, endDate, zipCodeOverride = null) {
|
|
const { order } = this;
|
|
if (!this.billToAccountNumber) {
|
|
return null;
|
|
}
|
|
|
|
const { vehicle } = this.order;
|
|
let lineItems = [
|
|
...(order.lineItems.supportingItems ?? []),
|
|
...(order.lineItems.vaps ?? []),
|
|
...(order.lineItems.glassParts ?? [])
|
|
];
|
|
lineItems = getLineItemsFlattened(lineItems);
|
|
lineItems = lineItems.map((lineItem) => ({
|
|
partNumber: lineItem.partNumber,
|
|
partType: lineItem.partType
|
|
}));
|
|
const glassPieces = order.damage.glassToReplace
|
|
? convertGlassPieceToBackEndCompatibleFormat(order.damage.glassToReplace)
|
|
: [];
|
|
const payload = {
|
|
startDate,
|
|
endDate,
|
|
applicationName: applicationConfig.APPLICATION_NAME,
|
|
billToAccountNumber: this.billToAccountNumber,
|
|
parentAccountNumber: order.parentAccountNumber, // this.payment.parentAccountNumber,
|
|
carId: vehicle.carId,
|
|
lineItems,
|
|
glassPieces,
|
|
eon: order.eon,
|
|
coverage: {
|
|
status: '',
|
|
deductible: 0,
|
|
additionalAuthFlag: ''
|
|
},
|
|
partSelection: {
|
|
hasAnsweredPartQuestions: !!order.damage.partQuestionAnswers?.length,
|
|
hasAnsweredMoldingQuestions: !!order.damage.moldingQuestionAnswers?.length,
|
|
hasAnsweredCapabilityQuestions: !!order.damage.capabilityQuestionAnswers?.length,
|
|
hasManuallySelectedParts:
|
|
!!this.applicationUser.pageData['vehicle-parts']?.partsOrQuestions
|
|
.length
|
|
},
|
|
vehicle: {
|
|
year: vehicle.year,
|
|
make: vehicle.make,
|
|
model: vehicle.model,
|
|
style: vehicle.style,
|
|
vin: vehicle.vin ?? ''
|
|
},
|
|
zipCode: zipCodeOverride ?? order.serviceLocation.zipCode
|
|
};
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetMobileTimeSlots.method,
|
|
endpoint: endpoints.GetMobileTimeSlots.url,
|
|
payload
|
|
});
|
|
},
|
|
getShopTimeSlots(startDate, endDate, shopAppointmentType, providerNumber) {
|
|
const { order } = this;
|
|
if (!this.billToAccountNumber || !providerNumber) {
|
|
return null;
|
|
}
|
|
const { vehicle } = this.order;
|
|
|
|
let lineItems = [
|
|
...(order.lineItems.supportingItems ?? []),
|
|
...(order.lineItems.vaps ?? []),
|
|
...(order.lineItems.glassParts ?? [])
|
|
];
|
|
lineItems = getLineItemsFlattened(lineItems);
|
|
lineItems = lineItems.map((lineItem) => ({
|
|
partNumber: lineItem.partNumber,
|
|
partType: lineItem.partType
|
|
}));
|
|
const glassPieces = order.damage.glassToReplace
|
|
? convertGlassPieceToBackEndCompatibleFormat(order.damage.glassToReplace)
|
|
: [];
|
|
const payload = {
|
|
providerNumber,
|
|
startDate,
|
|
endDate,
|
|
shopAppointmentType: (shopAppointmentType === AppointmentTypeStrings.IN_SHOP
|
|
|| shopAppointmentType === AppointmentTypeStrings.DROP_OFF) ? 'InShopOrDropoff' : shopAppointmentType,
|
|
applicationName: applicationConfig.APPLICATION_NAME,
|
|
billToAccountNumber: this.billToAccountNumber,
|
|
parentAccountNumber: this.order.parentAccountNumber, // this.payment.parentAccountNumber,
|
|
carId: vehicle.carId,
|
|
lineItems,
|
|
glassPieces,
|
|
eon: order.eon,
|
|
coverage: {
|
|
status: '',
|
|
deductible: 0,
|
|
additionalAuthFlag: ''
|
|
},
|
|
partSelection: {
|
|
hasAnsweredPartQuestions: !!order.damage.partQuestionAnswers?.length,
|
|
hasAnsweredMoldingQuestions: !!order.damage.moldingQuestionAnswers?.length,
|
|
hasAnsweredCapabilityQuestions: !!order.damage.capabilityQuestionAnswers?.length,
|
|
hasManuallySelectedParts: !!this.applicationUser.pageData['vehicle-parts']?.partsOrQuestions.length
|
|
},
|
|
vehicle: {
|
|
year: vehicle.year,
|
|
make: vehicle.make,
|
|
model: vehicle.model,
|
|
style: vehicle.style,
|
|
vin: vehicle.vin ?? ''
|
|
}
|
|
};
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetShopTimeSlots.method,
|
|
endpoint: endpoints.GetShopTimeSlots.url,
|
|
payload,
|
|
bailoutOnError: false
|
|
});
|
|
},
|
|
async getWipers() {
|
|
const { carId } = this.order.vehicle;
|
|
const serviceZipCode = this.order.serviceLocation.zipCode;
|
|
|
|
return globalMethods
|
|
.callHttpClient({
|
|
method: endpoints.GetWipers.method,
|
|
endpoint: `${endpoints.GetWipers.url}/${carId}/${serviceZipCode}`
|
|
})
|
|
.catch((error) => {
|
|
// The wiper service sometimes returns 500s on legitimate carId/zipCode combination - return empty array instead of breaking flow
|
|
console.error(error);
|
|
return [];
|
|
});
|
|
},
|
|
|
|
async getRainDefense() {
|
|
return globalMethods
|
|
.callHttpClient({
|
|
method: endpoints.GetRainDefense.method,
|
|
endpoint: `${endpoints.GetRainDefense.url}`
|
|
})
|
|
.catch((error) => {
|
|
// The wiper service sometimes returns 500s on legitimate carId/zipCode combination - return empty array instead of breaking flow
|
|
console.error(error);
|
|
return [];
|
|
});
|
|
},
|
|
|
|
getSafeliteProviders(zipCode, radius = 100) {
|
|
return this.getProviders(zipCode, radius, true)
|
|
},
|
|
|
|
getTpaAndSafeliteProviders(zipCode, provderNameSearchString = "") {
|
|
const { parentAccountNumber } = this.order;
|
|
const carId = this.order.vehicle.carId;
|
|
const damageType = this.damage.isRepair ? 'Repair' : 'Install';
|
|
|
|
const parts = getLineItemsFlattened(this.order.lineItems.glassParts);
|
|
const partNumbers = this.damage.isRepair ? partNumberStrings.REPAIR : parts.map((part) => part.partNumber).join(',');
|
|
|
|
let url = `${endpoints.GetTpaAndSafeliteProviders.url}/${zipCode}?accountNumber=${parentAccountNumber}&carId=${carId}&damageType=${damageType}&partNumbers=${partNumbers}`;
|
|
if (provderNameSearchString) {
|
|
url += `&providerNameSearchString=${provderNameSearchString}`;
|
|
}
|
|
return new Promise((resolve, reject) => {
|
|
globalMethods.callHttpClient({
|
|
method: endpoints.GetTpaAndSafeliteProviders.method,
|
|
endpoint: url
|
|
}).then((response) => resolve(response), (error) => reject(error));
|
|
});
|
|
},
|
|
|
|
getProviders(zipcode, radius, safeliteOnly) {
|
|
const { carId, isBigTruck } = this.order.vehicle;
|
|
const damageType = this.damage.isRepair ? 'Repair' : 'Replace';
|
|
const { parentAccountNumber } = this.order;
|
|
const partsWithRecal = getTopLevelGlassPartsWithRecal(this.order.lineItems.glassParts);
|
|
const windshieldPartWithRecal = partsWithRecal?.length > 0 ? partsWithRecal[0] : null;
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetProviders.method,
|
|
endpoint: endpoints.GetProviders.url(
|
|
zipcode,
|
|
damageType,
|
|
radius,
|
|
parentAccountNumber,
|
|
safeliteOnly,
|
|
carId,
|
|
windshieldPartWithRecal?.partNumber,
|
|
!!isBigTruck
|
|
)
|
|
});
|
|
},
|
|
|
|
getCarrierAccountInfo() {
|
|
return new Promise((resolve, reject) => {
|
|
globalMethods.callHttpClient({
|
|
method: endpoints.GetAccountInfo.method,
|
|
endpoint: endpoints.GetAccountInfo.url + this.order.parentAccountNumber
|
|
}).then((response) => {
|
|
this.order.carrierPhoneNumber = response.data.phoneNumber;
|
|
return resolve(response.data);
|
|
}).catch((error) => reject(error));
|
|
});
|
|
},
|
|
async getRecalParts() {
|
|
const { glassParts } = this.lineItems;
|
|
const { carId } = this.vehicle;
|
|
const { parentAccountNumber, referralSequenceNumber } = this.order;
|
|
const { zipCode } = this.order.serviceLocation;
|
|
|
|
if (glassParts && glassParts.length > 0) {
|
|
const recalPromises = [];
|
|
glassParts.forEach((glassPart) => {
|
|
if (glassPart.requiresRecalibration) {
|
|
const partNumberChecked = glassPart.partNumber;
|
|
recalPromises.push(globalMethods
|
|
.callHttpClient({
|
|
method: endpoints.GetRecalParts.method,
|
|
endpoint: endpoints.GetRecalParts.url(
|
|
carId,
|
|
partNumberChecked,
|
|
glassPart.recalibrationType,
|
|
parentAccountNumber,
|
|
zipCode,
|
|
applicationConfig.APPLICATION_NAME,
|
|
referralSequenceNumber
|
|
)
|
|
})
|
|
.then((response) => {
|
|
const recalResponse = response.data;
|
|
if (recalResponse && recalResponse.recalibrationParts && recalResponse.recalibrationParts.length > 0) {
|
|
this.addGlassPartRecalibrationInfo(partNumberChecked, recalResponse.recalibrationParts);
|
|
}
|
|
}));
|
|
}
|
|
});
|
|
await Promise.allSettled(recalPromises);
|
|
}
|
|
},
|
|
addGlassPartRecalibrationInfo(partNumber, recalPartArray) {
|
|
const glassPart = this.lineItems.glassParts.find((gp) => gp.partNumber === partNumber);
|
|
if (glassPart) {
|
|
for (const recalPartInformation of recalPartArray) {
|
|
const recalChildPart = glassPart.childParts?.find((cp) => cp.partNumber === recalPartInformation.partNumber);
|
|
if (!recalChildPart) {
|
|
if (!Array.isArray(glassPart.childParts) || !glassPart.childParts.length) {
|
|
glassPart.childParts = [];
|
|
}
|
|
glassPart.childParts.push(recalPartInformation);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
async getGlassFees() {
|
|
const { insuranceCoverage, vehicle } = this.order;
|
|
const { glassParts } = this.lineItems;
|
|
const { isRepair } = this.damage;
|
|
const { defaultProviderNumber, provider, zipCode } = this.order.serviceLocation;
|
|
const damageType = isRepair ? 'Repair' : 'Install';
|
|
const facilityType = this.isMobileAppointment ? 'Mobile' : 'InShop';
|
|
const providerToUse = provider?.providerNumber ?? defaultProviderNumber;
|
|
const partNumberListQueryString = getPartNumbersListForQueryString(glassParts, 'PartNumbers');
|
|
|
|
if (!this.billToAccountNumber || !providerToUse) {
|
|
return null
|
|
}
|
|
|
|
const params = new URLSearchParams({
|
|
serviceType: damageType,
|
|
facilityType,
|
|
parentAccountNumber: this.order.parentAccountNumber,
|
|
billToAccountNumber: this.billToAccountNumber,
|
|
isPremiumAppointment: false,
|
|
isItacOptimized: insuranceCoverage.isItacOptimized,
|
|
zipCode,
|
|
coverageStatus: coverageStatuses.mapToApi(insuranceCoverage.coverageStatus),
|
|
coverageType: coverageType.mapToApi(insuranceCoverage.coverageType),
|
|
providerNumber: providerToUse,
|
|
carId: vehicle.carId
|
|
});
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetGlassFees.method,
|
|
endpoint: `${endpoints.GetGlassFees.url}?${params.toString()}${partNumberListQueryString}`
|
|
});
|
|
},
|
|
async getSupportingItems() {
|
|
const { glassParts } = this.lineItems;
|
|
const { carId } = this.vehicle;
|
|
const { isRepair, numberOfChips } = this.damage;
|
|
|
|
return globalMethods
|
|
.callHttpClient({
|
|
method: endpoints.GetSupportingItems.method,
|
|
endpoint: endpoints.GetSupportingItems.url,
|
|
payload: {
|
|
carId,
|
|
damageType: isRepair ? 'Repair' : 'Replace',
|
|
parentAccountNumber: applicationConfig.CASH_PARENT_ACCOUNT_NUMBER,
|
|
parts: glassParts ?? [],
|
|
numberOfRepairChips: isRepair ? numberOfChips : 0
|
|
}
|
|
});
|
|
},
|
|
|
|
async getITACPriceOrderItems(availableLineItems) {
|
|
const { policy, vehicle, contactInfo, serviceLocation, insuranceCoverage } = this.order;
|
|
const response = await globalMethods
|
|
.callHttpClient({
|
|
method: endpoints.GetITACPriceOrderItems.method,
|
|
endpoint: endpoints.GetITACPriceOrderItems.url,
|
|
payload: {
|
|
lineItems: getLineItemsFlattened(availableLineItems),
|
|
ServerData: this.order.lineItems.serverData,
|
|
Customer: {
|
|
PhoneNumber: contactInfo.servicePhone,
|
|
State: policy.damageState || this.order.customer.address.state,
|
|
ZipCode: policy.policyZipCode
|
|
},
|
|
Account: {
|
|
ParentAccountNumber: this.order.parentAccountNumber,
|
|
LineOfBusiness: 'PERSONAL'
|
|
},
|
|
Provider: {
|
|
ProviderNumber: this.providerNumber,
|
|
ProviderCtuNumber: serviceLocation.zipCodeCtu,
|
|
ProviderState: serviceLocation.state
|
|
},
|
|
Vehicle: {
|
|
CarId: vehicle.carId,
|
|
Year: vehicle.year,
|
|
Make: vehicle.make,
|
|
Model: vehicle.model
|
|
},
|
|
Insurance: {
|
|
Deductible: this.currentDeductible ?? 0,
|
|
PolicyNumber: policy.policyNumber,
|
|
CoverageStatus: insuranceCoverage.coverageStatus,
|
|
CoverageType: insuranceCoverage.coverageType
|
|
},
|
|
Order: {
|
|
Eon: this.order.eon,
|
|
ReferralNumber: this.order.referralNumber,
|
|
ReferralSequenceNumber: this.order.referralSequenceNumber,
|
|
ReferralDate: `${this.order.referralDate}Z`,
|
|
ServiceZipCode: serviceLocation.zipCode,
|
|
IsReplacement: !this.isRepair,
|
|
IsOEMRequest: this.hasOemEndorsement
|
|
}
|
|
}
|
|
});
|
|
|
|
const { lineItems, serverData, isItac, primaryBillToNumber, partsWerePriced, isItacOptimized } = response.data;
|
|
|
|
if (serverData) {
|
|
this.order.lineItems.serverData = serverData;
|
|
}
|
|
|
|
if (partsWerePriced) {
|
|
this.updateIsItacOptimized(isItacOptimized);
|
|
if (isItac) {
|
|
// if the ITAC Pricing API call returns isItac = true then we should switch to ITAC coverage type
|
|
this.updateCoverageType(coverageType.ITAC);
|
|
} else if (this.isITAC) {
|
|
// If the ITAC pricing API call returns isItac = false, and we are currently ITAC in the store then we should switch to deductible coverage type
|
|
this.updateCoverageType(coverageType.Deductible);
|
|
}
|
|
}
|
|
|
|
if (primaryBillToNumber && primaryBillToNumber.length !== 0) {
|
|
this.issConfig.billToAccountNumber = primaryBillToNumber;
|
|
} else {
|
|
await this.getBillToInfo();
|
|
}
|
|
|
|
if (lineItems) {
|
|
const retAvailableLineItems = addPricesToLineItems(availableLineItems, lineItems);
|
|
return retAvailableLineItems;
|
|
}
|
|
|
|
return availableLineItems;
|
|
},
|
|
|
|
async getCombinedQuote(availableLineItems) {
|
|
if (!availableLineItems || availableLineItems.length === 0 || !this.providerNumber) {
|
|
return [];
|
|
}
|
|
|
|
const {
|
|
vehicle,
|
|
serviceLocation,
|
|
policy,
|
|
eon,
|
|
referralNumber,
|
|
referralDate,
|
|
referralSequenceNumber,
|
|
lineItems
|
|
} = this.order;
|
|
|
|
const availableLineItemsFiltered = availableLineItems.filter((lineItem) => !!(lineItem.partNumber));
|
|
|
|
const lineItemsWithOnlyPartNumbers = availableLineItemsFiltered.map((lineItem) => ({ partNumber: lineItem.partNumber }));
|
|
|
|
const payload = {
|
|
ParentAccountNumber: this.order.parentAccountNumber,
|
|
BillToAccountNumber: this.billToAccountNumber,
|
|
ProviderNumber: this.providerNumber,
|
|
CarId: vehicle.carId,
|
|
Make: vehicle.make,
|
|
Model: vehicle.model,
|
|
Year: vehicle.year,
|
|
EON: eon,
|
|
ZipCode: policy.policyZipCode,
|
|
State: this.order.customer.address.state,
|
|
ReferralNumber: referralNumber,
|
|
ReferralDate: referralDate,
|
|
ReferralSequenceNumber: referralSequenceNumber,
|
|
ServiceZipCode: serviceLocation.zipCode,
|
|
IsReplacement: !this.isRepair,
|
|
ServerData: lineItems.serverData,
|
|
LineItems: lineItemsWithOnlyPartNumbers,
|
|
FeatureToggles: getFeatureTogglesPayloadObject(this.experimentSettings)
|
|
};
|
|
|
|
const response = await globalMethods
|
|
.callHttpClient({
|
|
method: endpoints.GetCombinedQuote.method,
|
|
endpoint: endpoints.GetCombinedQuote.url,
|
|
payload
|
|
})
|
|
.catch((error) => {
|
|
console.error(error);
|
|
return [];
|
|
});
|
|
|
|
const { lineItems: pricedLinedItems, serverData } = response.data;
|
|
|
|
if (serverData) {
|
|
this.order.lineItems.serverData = serverData;
|
|
}
|
|
|
|
if (pricedLinedItems) {
|
|
return addPricesToLineItems(availableLineItems, pricedLinedItems);
|
|
}
|
|
return availableLineItems;
|
|
},
|
|
|
|
getMobileFeePart(serviceZipCode) {
|
|
const { vehicle, insuranceCoverage } = this.order;
|
|
const recalParts = getRecalPartNumbers(this.order.lineItems.glassParts);
|
|
if (!this.billToAccountNumber || !this.providerNumber) {
|
|
return null;
|
|
}
|
|
|
|
const params = buildURLSearchParams({
|
|
serviceType: this.damage.isRepair ? 'Repair' : 'Install',
|
|
facilityType: 'Mobile',
|
|
parentAccountNumber: this.order.parentAccountNumber,
|
|
billToAccountNumber: this.billToAccountNumber,
|
|
isItacOptimized: insuranceCoverage.isItacOptimized,
|
|
providerNumber: this.providerNumber,
|
|
carId: vehicle.carId,
|
|
zipCode: serviceZipCode,
|
|
partNumbers: recalParts,
|
|
coverageStatus: coverageStatuses.mapToApi(insuranceCoverage.coverageStatus),
|
|
coverageType: coverageType.mapToApi(insuranceCoverage.coverageType)
|
|
});
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetMobileFeePart.method,
|
|
endpoint: `${endpoints.GetMobileFeePart.url}?${params.toString()}`
|
|
});
|
|
},
|
|
getServiceabilityDetails(serviceZipCode) {
|
|
const { damage, lineItems, parentAccountNumber, vehicle } = this.order;
|
|
const { carId } = vehicle;
|
|
const flattenedGlassParts = getLineItemsFlattened(lineItems.glassParts);
|
|
const lineItemsList = flattenedGlassParts.map((part) => part.partNumber).join(',');
|
|
|
|
let 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
|
|
});
|
|
},
|
|
lookupVehicleByVin(vin) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LookupVehicleByVin.method,
|
|
endpoint: endpoints.LookupVehicleByVin.url,
|
|
payload: {
|
|
vin
|
|
},
|
|
bailoutOnError: false
|
|
});
|
|
},
|
|
|
|
async setVehicle() {
|
|
const encodedMake = encodeURIComponent(this.order.vehicle.make);
|
|
const encodedModel = encodeURIComponent(this.order.vehicle.model);
|
|
const encodedStyle = encodeURIComponent(this.order.vehicle.style);
|
|
const response = await globalMethods
|
|
.callHttpClient({
|
|
method: endpoints.GetVehicle.method,
|
|
endpoint: `${endpoints.GetVehicle.url}/${this.order.vehicle.year}/${encodedMake}/${encodedModel}/${encodedStyle}`,
|
|
payload: {}
|
|
});
|
|
this.updateVehicle(response.data);
|
|
return response;
|
|
},
|
|
|
|
setSaveSessionInfo(response) {
|
|
this.order.referralNumber = response.referralNumber;
|
|
this.order.referralSequenceNumber = response.referralSequenceNumber;
|
|
this.order.referralDate = response.referralDate;
|
|
this.order.referralCorrelationId = response.referralCorrelationId;
|
|
this.order.eon = response.eon;
|
|
this.order.workOrderId = response.workOrderId;
|
|
this.order.workOrderNumber = response.workOrderNumber;
|
|
this.order.settledTenderAmount = response.settledTenderAmount;
|
|
this.order.lockToken = response.lockToken;
|
|
this.order.customerPortalLoginToken = response.customerPortalLoginToken;
|
|
this.applicationUser.savedSessionId = response.savedSessionId;
|
|
this.applicationUser.crmCustomerId = response.crmCustomerId.toString();
|
|
},
|
|
|
|
saveSession({ submitAfterSave, createWorkOrderNumberForPIA, bailoutOnError }) {
|
|
const { vehicle, damage, policy, customer, contactInfo, payment,
|
|
lineItems, serviceLocation, schedule, insuranceCoverage } = this.order;
|
|
|
|
// We don't want to save the session for a loaded session until the car ID is set
|
|
if (this.order.loadedFromDupeCheck && !vehicle.carId) {
|
|
return Promise.resolve(null);
|
|
}
|
|
|
|
if (this.hasSubmittedOrder()) {
|
|
return Promise.resolve(null);
|
|
}
|
|
|
|
const loadedFromDupeCheck = !!(this.order.loadedFromDupeCheck && !this.order.loadedSessionClearedPreviousData);
|
|
const newGlassToReplace = convertGlassPieceNamingForApi(damage.glassToReplace);
|
|
const shouldClearOnSubmit = this.isVerified && this.isDeductible;
|
|
const payloadGlassParts = setClearOnSubmit(lineItems.glassParts, shouldClearOnSubmit);
|
|
const payloadSupportingItems = setClearOnSubmit(lineItems.supportingItems, shouldClearOnSubmit);
|
|
const payloadVapsItems = setClearOnSubmit(lineItems.vaps, shouldClearOnSubmit);
|
|
const payloadFeeItems = setClearOnSubmit(lineItems.feeItems, shouldClearOnSubmit);
|
|
|
|
const payload = {
|
|
applicationUser: {
|
|
crmCustomerId: this.applicationUser.crmCustomerId,
|
|
experiments: this.applicationUser.experiments,
|
|
lastPage: this.applicationUser.lastPageVisited,
|
|
pageData: this.applicationUser.pageData,
|
|
savedSessionId: this.applicationUser.savedSessionId
|
|
},
|
|
vehicle: {
|
|
year: vehicle.year,
|
|
make: vehicle.make,
|
|
model: vehicle.model,
|
|
style: vehicle.style,
|
|
vin: vehicle.vin,
|
|
carId: vehicle.carId,
|
|
licensePlateNumber: vehicle.registration?.licensePlate,
|
|
isBigTruck: vehicle.isBigTruck
|
|
},
|
|
damage: {
|
|
numberOfChips: damage.numberOfChips,
|
|
glassToReplace: newGlassToReplace,
|
|
isRepair: damage.isRepair,
|
|
partQuestionAnswers: damage.partQuestionAnswers,
|
|
moldingQuestionAnswers: damage.moldingQuestionAnswers,
|
|
capabilityQuestionAnswers: damage.capabilityQuestionAnswers,
|
|
dateOfLoss: policy.dateOfLoss,
|
|
damageCause: policy.damageCause,
|
|
damageState: policy.damageState,
|
|
damageCity: policy.damageCity,
|
|
isDamageGlassOnly: policy.isDamageGlassOnly
|
|
},
|
|
policy: {
|
|
policyHolder: {
|
|
policyFirstName: customer.firstName,
|
|
policyLastName: customer.lastName,
|
|
policyPhoneNumber: contactInfo.servicePhone,
|
|
policyEmail: customer.emailAddress,
|
|
policyState: customer.address.state
|
|
},
|
|
policyNumber: policy.policyNumber,
|
|
policyZipCode: policy.policyZipCode,
|
|
originalDeductible: this.originalDeductible,
|
|
currentDeductible: this.currentDeductible,
|
|
OemEndorsement: this.hasOemEndorsement,
|
|
noCoverage: this.isNoComp,
|
|
isItac: this.isITAC,
|
|
cvrgEndorsementCode: policy.cvrgEndorsementCode ?? endorsementCodesForSelectedVehicle(vehicle),
|
|
endorsementQuestionAnswers: policy.endorsementQuestionAnswers
|
|
},
|
|
customer: {
|
|
address: {
|
|
streetAddress: customer.address?.streetAddress,
|
|
streetAddress2: customer.address?.streetAddress2,
|
|
city: customer.address?.city,
|
|
state: customer.address?.state,
|
|
zipCode: customer.address?.zipCode?.toString()
|
|
},
|
|
emailAddress: customer.emailAddress,
|
|
firstName: customer.firstName,
|
|
lastName: customer.lastName,
|
|
homePhone: contactInfo.extension && contactInfo.homePhone ? contactInfo.homePhone + contactInfo.extension : contactInfo.homePhone,
|
|
servicePhone: contactInfo.servicePhone,
|
|
alternativePhone: contactInfo.alternativePhone,
|
|
isSmsOptIn: contactInfo.requestTextUpdates ?? false
|
|
},
|
|
lineItems: {
|
|
glassParts: payloadGlassParts,
|
|
serverData: lineItems.serverData,
|
|
supportingItems: [...payloadSupportingItems, ...payloadFeeItems],
|
|
vaps: payloadVapsItems
|
|
},
|
|
insuranceCoverage: {
|
|
coverageType: insuranceCoverage.coverageType,
|
|
coverageStatus: insuranceCoverage.coverageStatus,
|
|
claimNumber: insuranceCoverage.claimNumber
|
|
},
|
|
payment: {
|
|
parentAccountNumber: this.order.parentAccountNumber ?? this.issConfig.parentAccountNumber,
|
|
billToAccountNumber: this.billToAccountNumber,
|
|
paypalToken: payment.paypalToken,
|
|
paymentMethod: payment.paymentMethod === paymentMethods.PayNow ? null : payment.paymentMethod,
|
|
nextGenSettledAmount: payment.nextGenSettledAmount,
|
|
CCToken: payment.creditCardToken
|
|
},
|
|
serviceLocation: {
|
|
address: {
|
|
streetAddress: serviceLocation.address,
|
|
city: serviceLocation.city,
|
|
state: serviceLocation.state,
|
|
zipCode: serviceLocation.zipCode,
|
|
zipCodeCtu: serviceLocation.zipCodeCtu
|
|
},
|
|
appointmentType: (serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE
|
|
|| serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP)
|
|
? AppointmentTypeStrings.MOBILE : serviceLocation.appointmentType,
|
|
isVehicleProtected: serviceLocation.isVehicleProtected,
|
|
provider: {
|
|
IsSafeliteProvider: serviceLocation?.IsSafeliteProvider,
|
|
providerNumber: this.providerNumber,
|
|
address: {
|
|
streetAddress: serviceLocation.provider?.address?.streetAddress,
|
|
city: serviceLocation.provider?.address?.city,
|
|
state: serviceLocation.provider?.address?.state,
|
|
zipCode: serviceLocation.provider?.address?.zipCode,
|
|
zipCodeCtu: serviceLocation.provider?.address?.zipCodeCtu
|
|
}
|
|
},
|
|
techNotes: contactInfo.notesForTechnician
|
|
},
|
|
schedule: {
|
|
date: schedule.date,
|
|
startTime: schedule.startTime,
|
|
endTime: schedule.endTime,
|
|
routeCode: schedule.routeCode,
|
|
jobMaxMinutes: schedule.jobMaxMinutes,
|
|
jobMinMinutes: schedule.jobMinMinutes
|
|
},
|
|
referralDate: this.order.referralDate,
|
|
referralNumber: this.order.referralNumber?.toString(),
|
|
referralCorrelationId: this.order.referralCorrelationId,
|
|
referralSequenceNumber: this.order.referralSequenceNumber,
|
|
eon: this.order.eon,
|
|
submitToMainframe: !!this.order.referralNumber,
|
|
createWorkOrderNumberForPIA,
|
|
lockToken: this.order.lockToken,
|
|
loadedFromDupeCheck,
|
|
submitAfterSave: !!submitAfterSave
|
|
};
|
|
|
|
return new Promise((resolve, reject) => {
|
|
globalMethods.callHttpClient({
|
|
method: endpoints.SaveSession.method,
|
|
endpoint: endpoints.SaveSession.url,
|
|
payload,
|
|
bailoutOnError
|
|
}).then((response) => {
|
|
if (loadedFromDupeCheck) {
|
|
this.order.loadedSessionClearedPreviousData = true;
|
|
}
|
|
resolve(response);
|
|
}, (error) => reject(error));
|
|
});
|
|
},
|
|
/**
|
|
* @function getCookieValueByName
|
|
* @param {object} payload
|
|
* referralNumber: the sv2 referral's referralNumber
|
|
* responseDate: the sv2 referral's referralDate or the responseDate associated with the returned duplicate-check record
|
|
* parentAccountNumber: the client's parentAccountNumber associated with the sv2 referral
|
|
* correlationId: the correlationId associated with the sv2 referral
|
|
* @summary
|
|
* Gets cookie value by name, returns empty string if not found.
|
|
* @returns {object} returns the response object for the load session api, which returns the sv2 referral information
|
|
*/
|
|
async getReferralByPayload(payload) {
|
|
return await globalMethods.callHttpClient({
|
|
method: endpoints.LoadSession.method,
|
|
endpoint: endpoints.LoadSession.url,
|
|
payload: {
|
|
referralNumber: payload.referralNumber,
|
|
referralDate: payload.responseDate,
|
|
parentAccountNumber: payload.parentAccountNumber,
|
|
referralCorrelationId: payload.correlationId
|
|
}
|
|
});
|
|
},
|
|
async loadSession(duplicate) {
|
|
const { order } = this;
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.LoadSession.method,
|
|
endpoint: endpoints.LoadSession.url,
|
|
payload: {
|
|
referralNumber: duplicate.referralNumber,
|
|
referralDate: duplicate.referralDate,
|
|
parentAccountNumber: order.parentAccountNumber,
|
|
referralCorrelationId: duplicate.correlationId
|
|
}
|
|
});
|
|
const { data } = response;
|
|
if (!data) {
|
|
return;
|
|
}
|
|
|
|
if (data?.customer) {
|
|
order.customer.firstName = data?.customer?.firstName;
|
|
order.customer.lastName = data?.customer?.lastName;
|
|
order.customer.emailAddress = data?.customer?.emailAddress;
|
|
|
|
order.contactInfo.extension = data?.customer?.homePhone?.slice(10);
|
|
order.contactInfo.homePhone = data?.customer?.homePhone?.slice(0, 10);
|
|
order.contactInfo.servicePhone = data?.customer?.servicePhone;
|
|
order.contactInfo.alternativePhone = data?.customer?.alternativePhone;
|
|
order.contactInfo.requestTextUpdates = data?.customer?.isSmsOptIn;
|
|
|
|
if (data?.customer?.address) {
|
|
order.customer.address.streetAddress = data.customer?.address?.streetAddress;
|
|
order.customer.address.streetAddress2 = data.customer?.address?.streetAddress2;
|
|
order.customer.address.city = data.customer?.address?.city;
|
|
order.customer.address.state = data.customer?.address?.state;
|
|
order.customer.address.zipCode = data.customer?.address?.zipCode;
|
|
}
|
|
}
|
|
|
|
if (data?.vehicle) {
|
|
order.vehicle.year = data?.vehicle?.year;
|
|
order.vehicle.make = data?.vehicle?.make;
|
|
order.vehicle.model = data?.vehicle?.model;
|
|
order.vehicle.style = data?.vehicle?.style;
|
|
}
|
|
|
|
if (this.isPolicyLookupSuccessful) {
|
|
if (data.insuranceCoverage) {
|
|
order.insuranceCoverage.coverageType = data?.insuranceCoverage?.coverageType;
|
|
order.insuranceCoverage.coverageStatus = data?.insuranceCoverage?.coverageStatus;
|
|
order.insuranceCoverage.claimNumber = data?.insuranceCoverage?.claimNumber;
|
|
} else if (data?.payment?.insuranceCoverage) {
|
|
if (data?.payment?.insuranceCoverage?.isVerified) {
|
|
order.insuranceCoverage.coverageStatus = coverageStatuses.VERIFIED;
|
|
}
|
|
order.insuranceCoverage.claimNumber = data?.payment?.insuranceCoverage?.claimNumber;
|
|
}
|
|
|
|
if (order.policy.vehicles.length !== 0 && data.vehicle?.carId) {
|
|
order.vehicle.registration.licensePlate = data?.vehicle?.licensePlateNumber;
|
|
if (data.vehicle.vin) {
|
|
const vehicle = order.policy.vehicles.find((v) => v.vin === data.vehicle.vin);
|
|
if (vehicle) {
|
|
const vehicleResponse = await this.lookupVehicleByVin(vehicle.vin);
|
|
if (vehicleResponse) {
|
|
this.updateVehicle({
|
|
...vehicleResponse.data,
|
|
policyVehicleId: vehicle.id,
|
|
vin: vehicle.vin
|
|
});
|
|
this.updateVehicleCoverage({
|
|
noCoverage: noCoverageForSelectedVehicle(vehicle),
|
|
deductible: deductibleForSelectedVehicle(vehicle),
|
|
repairWaived: repairWaivedForSelectedVehicle(vehicle),
|
|
endorsements: endorsementsForSelectedVehicle(vehicle)
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
order.referralNumber = data?.referralNumber;
|
|
order.referralDate = data?.referralDate;
|
|
order.referralCorrelationId = data?.referralCorrelationId;
|
|
order.referralSequenceNumber = data?.referralSequenceNumber;
|
|
order.eon = data?.eon;
|
|
order.loadedFromDupeCheck = true;
|
|
order.loadedSessionClearedPreviousData = false;
|
|
},
|
|
async loadSessionFromCookie(cookie) {
|
|
const { order, issConfig } = this;
|
|
const response = await this.getReferralByPayload(cookie);
|
|
const { data } = response;
|
|
if (data) {
|
|
order.customer.address.streetAddress = data.customer?.address?.streetAddress;
|
|
order.customer.address.streetAddress2 = data.customer?.address?.streetAddress2;
|
|
order.customer.address.city = data.customer?.address?.city;
|
|
order.customer.address.state = data.customer?.address?.state;
|
|
order.customer.address.zipCode = data.customer?.address?.zipCode;
|
|
order.customer.firstName = data?.customer?.firstName;
|
|
order.customer.lastName = data?.customer?.lastName;
|
|
order.customer.emailAddress = data?.customer?.emailAddress;
|
|
|
|
order.contactInfo.extension = data?.customer?.homePhone?.slice(10);
|
|
order.contactInfo.homePhone = data?.customer?.homePhone?.slice(0, 10);
|
|
order.contactInfo.servicePhone = data?.customer?.servicePhone;
|
|
order.contactInfo.alternativePhone = data?.customer?.alternativePhone;
|
|
order.contactInfo.requestTextUpdates = data?.customer?.isSmsOptIn;
|
|
|
|
if (data.insuranceCoverage) {
|
|
order.insuranceCoverage.coverageType = data?.insuranceCoverage?.coverageType;
|
|
order.insuranceCoverage.coverageStatus = data?.insuranceCoverage?.coverageStatus;
|
|
order.insuranceCoverage.claimNumber = data?.insuranceCoverage?.claimNumber;
|
|
} else if (data?.payment?.insuranceCoverage) {
|
|
if (data?.payment?.insuranceCoverage?.isVerified) {
|
|
order.insuranceCoverage.coverageStatus = coverageStatuses.VERIFIED;
|
|
}
|
|
order.insuranceCoverage.claimNumber = data?.payment?.insuranceCoverage?.claimNumber;
|
|
} else {
|
|
order.customer.firstName = data?.customer?.firstName;
|
|
order.customer.lastName = data?.customer?.lastName;
|
|
}
|
|
|
|
if (order.policy.vehicles.length !== 0 && data.vehicle?.carId) {
|
|
order.vehicle.registration.licensePlate = data?.vehicle?.licensePlateNumber;
|
|
if (data.vehicle.vin) {
|
|
const vehicle = order.policy.vehicles.find((v) => v.vin === data.vehicle.vin);
|
|
if (vehicle) {
|
|
const vehicleResponse = await this.lookupVehicleByVin(vehicle.vin);
|
|
if (vehicleResponse) {
|
|
this.updateVehicle({
|
|
...vehicleResponse.data,
|
|
policyVehicleId: vehicle.id,
|
|
vin: vehicle.vin
|
|
});
|
|
this.updateVehicleCoverage({
|
|
noCoverage: noCoverageForSelectedVehicle(vehicle),
|
|
deductible: deductibleForSelectedVehicle(vehicle),
|
|
repairWaived: repairWaivedForSelectedVehicle(vehicle),
|
|
endorsements: endorsementsForSelectedVehicle(vehicle)
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
order.vehicle.year = data.vehicle.year;
|
|
order.vehicle.make = data.vehicle.make;
|
|
order.vehicle.model = data.vehicle.model;
|
|
order.vehicle.style = data.vehicle.style;
|
|
}
|
|
|
|
order.policy.damageCause = data?.policy?.damageCause;
|
|
order.policy.damageCity = data?.policy?.damageCity;
|
|
order.policy.damageState = data?.policy?.damageState;
|
|
order.policy.dateOfLoss = data?.policy?.dateOfLoss;
|
|
order.policy.isDamageGlassOnly = data?.policy?.isDamageGlassOnly;
|
|
order.policy.policyNumber = data?.policy?.policyNumber;
|
|
order.policy.policyZipCode = data?.policy?.policyZipCode;
|
|
|
|
order.referralNumber = data?.referralNumber;
|
|
order.referralDate = data?.referralDate;
|
|
order.referralCorrelationId = data?.referralCorrelationId;
|
|
order.referralSequenceNumber = data?.referralSequenceNumber;
|
|
order.eon = data?.eon;
|
|
order.workOrderId = data?.workOrderId;
|
|
order.loadedFromCookie = true;
|
|
order.visitedDuplicateCheckPage = true;
|
|
order.loadedSessionClearedPreviousData = false;
|
|
issConfig.enableContinueFromCookie = false;
|
|
this.updateIsSafeliteProvider(data?.provider?.isSafeliteProvider);
|
|
}
|
|
|
|
return data;
|
|
},
|
|
updateCreditCardToken(token) {
|
|
this.order.payment.creditCardToken.subscriptionId = token.subscriptionId;
|
|
this.order.payment.creditCardToken.expMonth = token.expMonth;
|
|
this.order.payment.creditCardToken.expYear = token.expYear;
|
|
this.order.payment.creditCardToken.cardType = token.cardType;
|
|
this.order.payment.creditCardToken.billToPostalCode = token.billToPostalCode;
|
|
this.order.payment.creditCardToken.billToFirstName = token.billToFirstName;
|
|
this.order.payment.creditCardToken.billToLastName = token.billToLastName;
|
|
this.order.payment.creditCardToken.referenceNumber = token.referenceNumber;
|
|
this.order.payment.creditCardToken.authCode = token.authCode;
|
|
this.order.payment.creditCardToken.transactionId = token.transactionId;
|
|
this.order.payment.creditCardToken.transReferenceNumber = token.transReferenceNumber;
|
|
this.order.payment.creditCardToken.lastFour = token.lastFour;
|
|
},
|
|
updatePaypalToken(token) {
|
|
this.order.payment.paypalToken = token;
|
|
},
|
|
updateNextGenSettledAmount(amount) {
|
|
this.order.payment.nextGenSettledAmount = amount;
|
|
},
|
|
setSaveSessionPromise(promise) {
|
|
this.applicationUser.saveSessionPromise = promise;
|
|
},
|
|
|
|
clearSaveSessionPromise() {
|
|
this.applicationUser.saveSessionPromise = null;
|
|
},
|
|
|
|
saveEndorsementQuestionAnswers(endorsementQuestionAnswersArray) {
|
|
// if endorsement question answers have changed, reset question answers
|
|
const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(this.order.policy.endorsementQuestionAnswers, 'result');
|
|
const sortedEndorsementQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(endorsementQuestionAnswersArray, 'result');
|
|
const haveEndorsementQuestionAnswersChanged = sortedPreviousResultsArray?.length !== sortedEndorsementQuestionAnswersArray.length
|
|
|| !sortedPreviousResultsArray?.every((x, i) => x.result === sortedEndorsementQuestionAnswersArray[i].result);
|
|
|
|
if (haveEndorsementQuestionAnswersChanged) {
|
|
this.updateEndorsementQuestionAnswers(null);
|
|
}
|
|
|
|
this.updateEndorsementQuestionAnswers(endorsementQuestionAnswersArray);
|
|
},
|
|
|
|
saveVehicleDamage(isWindshieldRepair, selectedGlassToReplace, selectedWindshieldChipCount) {
|
|
const selectedGlassPassedInSorted = selectedGlassToReplace.slice().sort();
|
|
const isGlassToReplaceTheSame = this.order.damage.glassToReplace?.length === selectedGlassToReplace.length
|
|
&& this.order.damage.glassToReplace
|
|
.slice()
|
|
.sort()
|
|
.every((obj, index) => obj.glassLocation === selectedGlassPassedInSorted[index].glassLocation
|
|
&& obj.glassName === selectedGlassPassedInSorted[index].glassName);
|
|
const isWindshieldRepairTheSame = isWindshieldRepair === this.order.damage.isRepair;
|
|
const isChipCountTheSame = selectedWindshieldChipCount === this.order.damage.numberOfChips;
|
|
const isDamageChanging = !isGlassToReplaceTheSame || !isWindshieldRepairTheSame
|
|
|| (isWindshieldRepair && !isChipCountTheSame);
|
|
|
|
if (isDamageChanging) {
|
|
// Reset dependent state when changing
|
|
// Was resetGlassPartsState, added dependencies for SSR-290
|
|
this.resetPartsAndDependencies();
|
|
|
|
// Save new values
|
|
this.updateIsRepair(isWindshieldRepair);
|
|
this.updateNumberOfChips(isWindshieldRepair ? parseInt(selectedWindshieldChipCount) : null);
|
|
this.updateGlassToReplace(selectedGlassToReplace);
|
|
}
|
|
},
|
|
|
|
updateRegistration(registrationInfo) {
|
|
this.order.vehicle.registration.licensePlate = registrationInfo?.licensePlate;
|
|
this.order.vehicle.registration.address = registrationInfo?.address;
|
|
this.order.vehicle.registration.city = registrationInfo?.city;
|
|
this.order.vehicle.registration.state = registrationInfo?.state;
|
|
this.order.vehicle.registration.zipCode = registrationInfo?.zipCode;
|
|
this.order.vehicle.registration.firstName = registrationInfo?.firstName;
|
|
this.order.vehicle.registration.lastName = registrationInfo?.lastName;
|
|
},
|
|
updateServiceLocation(serviceLocationInfo) {
|
|
this.order.serviceLocation.address = serviceLocationInfo.address ?? this.order.serviceLocation.address;
|
|
this.order.serviceLocation.address2 = serviceLocationInfo.address2 ?? this.order.serviceLocation.address2;
|
|
this.order.serviceLocation.city = serviceLocationInfo.city ?? this.order.serviceLocation.city;
|
|
this.order.serviceLocation.state = serviceLocationInfo.state ?? this.order.serviceLocation.state;
|
|
this.order.serviceLocation.zipCode = serviceLocationInfo.zipCode ?? this.order.serviceLocation.zipCode;
|
|
this.order.serviceLocation.zipCodeCtu = serviceLocationInfo.zipCodeCtu ?? this.order.serviceLocation.zipCodeCtu;
|
|
this.order.serviceLocation.appointmentType = serviceLocationInfo.appointmentType ?? this.order.serviceLocation.appointmentType;
|
|
this.order.serviceLocation.isVehicleProtected = serviceLocationInfo.isVehicleProtected ?? this.order.serviceLocation.isVehicleProtected;
|
|
this.updateServiceLocationProvider(serviceLocationInfo.provider);
|
|
this.order.serviceLocation.tpaSearchRadius = serviceLocationInfo.tpaSearchRadius;
|
|
},
|
|
updateAppointmentType(appointmentType) {
|
|
this.order.serviceLocation.appointmentType = appointmentType;
|
|
},
|
|
updateServiceLocationProvider(providerInfo) {
|
|
this.order.serviceLocation.provider = {
|
|
providerNumber: providerInfo?.providerNumber,
|
|
address: {
|
|
streetAddress: providerInfo?.address?.streetAddress,
|
|
city: providerInfo?.address?.city,
|
|
state: providerInfo?.address?.state,
|
|
zipCode: providerInfo?.address?.zipCode,
|
|
zipCodeCtu: providerInfo?.address?.zipCodeCtu
|
|
},
|
|
companyName: providerInfo?.companyName,
|
|
phoneNumber: providerInfo?.phoneNumber
|
|
};
|
|
},
|
|
resetState() {
|
|
Object.assign(this, getDefaultState());
|
|
},
|
|
resetRegistrationState() {
|
|
this.order.vehicle.registration.licensePlate = null;
|
|
this.order.vehicle.registration.address = null;
|
|
this.order.vehicle.registration.city = null;
|
|
this.order.vehicle.registration.state = null;
|
|
this.order.vehicle.registration.zipCode = null;
|
|
this.order.vehicle.registration.firstName = null;
|
|
this.order.vehicle.registration.lastName = null;
|
|
},
|
|
resetServiceLocationAndDependencies() {
|
|
this.resetServiceLocationAppointmentType();
|
|
this.resetServiceLocationProvider();
|
|
this.resetSchedule();
|
|
},
|
|
resetServiceLocationAppointmentType() {
|
|
this.order.serviceLocation.appointmentType = null;
|
|
},
|
|
resetServiceLocationProvider() {
|
|
this.order.serviceLocation.provider = {
|
|
providerNumber: null,
|
|
companyName: null,
|
|
phoneNumber: null,
|
|
address: {
|
|
streetAddress: null,
|
|
city: null,
|
|
state: null,
|
|
zipCode: null,
|
|
zipCodeCtu: null
|
|
}
|
|
};
|
|
},
|
|
resetServiceLocationMobileAddress() {
|
|
this.order.serviceLocation.address = null;
|
|
this.order.serviceLocation.address2 = null;
|
|
this.order.serviceLocation.city = null;
|
|
this.order.serviceLocation.state = null;
|
|
this.order.serviceLocation.isVehicleProtected = null;
|
|
},
|
|
resetBailout() {
|
|
this.updatePageData({
|
|
page: issPageValues.BAILOUT_PAGE,
|
|
data: null
|
|
});
|
|
},
|
|
resetInsurance() {
|
|
this.order.insuranceCoverage.coverageStatus = coverageStatuses.PENDING;
|
|
this.order.insuranceCoverage.coverageType = coverageType.NONE;
|
|
this.order.insuranceCoverage.isItacOptimized = false;
|
|
this.order.insuranceCoverage.claimNumber = null;
|
|
},
|
|
updateGlassFees(feeData) {
|
|
if (feeData == null) {
|
|
this.order.lineItems.feeItems = null;
|
|
return;
|
|
}
|
|
|
|
feeData.forEach((fee) => {
|
|
if (fee.partNumber === partTypeStrings.MOBILE_FEE) {
|
|
this.updateMobileFee(fee);
|
|
} else if (fee.partNumber === partNumberStrings.RECYCLE_FEE) {
|
|
this.updateRecycleFee(fee);
|
|
} else if (fee.partNumber === partNumberStrings.LABOR2) {
|
|
// Do not add Labor2 to feeItems since it's already been added to supportingItems
|
|
this.addPartNumberFeeItem(null, partNumberStrings.LABOR2);
|
|
}else if (fee.partNumber === partNumberStrings.TESLA_THS_SRVCE) {
|
|
// Do not add Tesla THS Service Fee to feeItems, it is a child part already
|
|
} else {
|
|
this.addPartNumberFeeItem(fee, fee.partNumber);
|
|
}
|
|
});
|
|
},
|
|
updateSupportingItems(partsData) {
|
|
if (partsData == null) {
|
|
this.order.lineItems.supportingItems = [];
|
|
return;
|
|
}
|
|
|
|
// Process Recycle Fee
|
|
this.updateRecycleFee(partsData.find((rf) => rf.partNumber === partNumberStrings.RECYCLE_FEE));
|
|
|
|
// Remove Recycle Fee from supporting items since it's already been added to feeItems
|
|
let supportingItems = partsData.filter((i) => i.partNumber !== partNumberStrings.RECYCLE_FEE);
|
|
|
|
// Remove Repair Supplies Fee, which is hidden for ISS except in scenarios not yet implemented
|
|
supportingItems = supportingItems.filter((i) => i.partNumber !== partNumberStrings.SUPPLIES_REPAIR);
|
|
|
|
this.order.lineItems.supportingItems = supportingItems;
|
|
},
|
|
|
|
updateVaps(partsData) {
|
|
this.order.lineItems.vaps = partsData;
|
|
},
|
|
|
|
updateServicePackage(packageName) {
|
|
this.order.servicePackage = packageName;
|
|
},
|
|
|
|
updateMobileFee(fee) {
|
|
const isMobileFeeHidden = getExperimentSettingValue(this.experimentSettings, experimentSettings.ISS_FEATURE_TOGGLE_IS_MOBILE_FEE_HIDDEN) === 'true';
|
|
const isMSRFee = fee?.partNumber === partNumberStrings.RECAL_MOBILE || fee?.partNumber === partNumberStrings.RECAL_MOBILEDUAL;
|
|
// Mobile Fee is only added for NO COMP or ITAC and is NOT hidden
|
|
// MSR Fee is added for all orders
|
|
if ((fee && this.isVerified && (this.isNoComp || this.isITAC) && !isMobileFeeHidden) || isMSRFee) {
|
|
this.addPartTypeFeeItem(fee, partTypeStrings.MOBILE_FEE);
|
|
} else {
|
|
this.addPartTypeFeeItem(null, partTypeStrings.MOBILE_FEE);
|
|
}
|
|
},
|
|
|
|
updateRecycleFee(fee) {
|
|
const isRecycleFeeHidden = getExperimentSettingValue(this.experimentSettings, experimentSettings.ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_HIDDEN) === 'true';
|
|
// Recycle Fee is only added for NO COMP or ITAC and has Windshield Replacement and is NOT hidden
|
|
if (fee && this.isVerified && (this.isNoComp || this.isITAC) && this.hasWindshieldReplacement && !isRecycleFeeHidden) {
|
|
this.addPartNumberFeeItem(fee, partNumberStrings.RECYCLE_FEE);
|
|
} else {
|
|
this.addPartNumberFeeItem(null, partNumberStrings.RECYCLE_FEE);
|
|
}
|
|
},
|
|
|
|
addPartNumberFeeItem(feeItem, partNumber) {
|
|
this.addFeeItem(feeItem, (fi) => fi.partNumber !== partNumber);
|
|
},
|
|
|
|
addPartTypeFeeItem(feeItem, partType) {
|
|
this.addFeeItem(feeItem, (fi) => fi.partType !== partType);
|
|
},
|
|
|
|
addFeeItem(feeItem, filter) {
|
|
let { feeItems } = this.order.lineItems;
|
|
// Remove all fee items with the given filter
|
|
feeItems = feeItems.filter(filter);
|
|
if (feeItem) {
|
|
feeItems.push(feeItem);
|
|
}
|
|
this.order.lineItems.feeItems = feeItems;
|
|
},
|
|
|
|
async setPriceAndSalesTaxForOrderLineItems() {
|
|
let lineItemsToTax;
|
|
if (this.isVerified && !this.isDeductible) {
|
|
lineItemsToTax = [
|
|
...(this.order.lineItems.supportingItems ?? []),
|
|
...(this.order.lineItems.glassParts ?? []),
|
|
...(this.order.lineItems.otherParts ?? []),
|
|
...(this.order.lineItems.vaps ?? []),
|
|
...(this.order.lineItems.feeItems ?? [])
|
|
];
|
|
} else {
|
|
lineItemsToTax = [
|
|
...(this.order.lineItems.vaps ?? []),
|
|
...(this.order.lineItems.feeItems ?? [])
|
|
];
|
|
}
|
|
|
|
if (lineItemsToTax && lineItemsToTax.length > 0) {
|
|
await this.getTaxOrderItems(lineItemsToTax);
|
|
}
|
|
},
|
|
|
|
updateVehicle(vehicle) {
|
|
// Assuming that the method caller pass all the properties.
|
|
// otherwise need to check for undefined for every property.
|
|
if (this.order.vehicle.carId !== vehicle.carId
|
|
|| (!this.order.vehicle.vin && vehicle.vin)
|
|
|| (this.order.vehicle.vin && vehicle.vin && this.order.vehicle.vin !== vehicle.vin)) {
|
|
this.order.vehicle.vin = vehicle.vin;
|
|
}
|
|
|
|
this.order.vehicle.policyVehicleId = vehicle.policyVehicleId;
|
|
this.order.vehicle.carId = vehicle.carId;
|
|
this.order.vehicle.category = vehicle.category;
|
|
this.order.vehicle.year = vehicle.year;
|
|
this.order.vehicle.make = vehicle.make;
|
|
this.order.vehicle.model = vehicle.model;
|
|
this.order.vehicle.style = vehicle.style;
|
|
this.order.vehicle.imageUrl = vehicle.imageUrl;
|
|
this.order.vehicle.imageVifNumber = vehicle.imageVifNumber;
|
|
this.order.vehicle.imageColor = vehicle.imageVifColor;
|
|
this.order.vehicle.isBigTruck = vehicle.isBigTruck;
|
|
this.order.vehicle.canSafeliteService = vehicle.canSafeliteService;
|
|
|
|
this.updateSupportingItems(null);
|
|
this.updateVaps(null);
|
|
this.updateServicePackage(null);
|
|
},
|
|
|
|
updateVehicleCoverage(coverage) {
|
|
if (coverage.noCoverage) {
|
|
if (this.isNoCompQuoteEnabled) {
|
|
this.updateCoverageType(coverageType.NO_COMP);
|
|
} else {
|
|
this.updateCoverageType(coverageType.NONE);
|
|
}
|
|
} else {
|
|
this.updateCoverageType(coverageType.Deductible);
|
|
}
|
|
|
|
if (!this.isClaimRegistrationRequired) {
|
|
this.updateCoverageStatus(coverageStatuses.VERIFIED);
|
|
}
|
|
|
|
this.order.policy.deductible.replace = coverage.deductible;
|
|
this.order.policy.deductible.repair = coverage?.repairWaived ?? false ? 0 : coverage.deductible;
|
|
this.order.policy.endorsements = coverage?.endorsements;
|
|
this.order.policy.cvrgEndorsementCode = coverage?.cvrgEndorsementCode;
|
|
|
|
this.order.originalDeductible.replace = this.order.policy.deductible.replace;
|
|
this.order.currentDeductible.replace = this.order.policy.deductible.replace;
|
|
this.order.originalDeductible.repair = this.order.policy.deductible.repair;
|
|
this.order.currentDeductible.repair = this.order.policy.deductible.repair;
|
|
},
|
|
|
|
resetOrder() {
|
|
this.order.referralNumber = null;
|
|
this.order.referralSequenceNumber = null;
|
|
this.order.referralDate = null;
|
|
this.order.referralSequenceNumber = null;
|
|
this.order.workOrderId = null;
|
|
this.order.workOrderNumber = null;
|
|
this.order.settledTenderAmount = null;
|
|
this.order.lockToken = null;
|
|
this.order.eon = null;
|
|
this.order.originalDeductible.repair = null;
|
|
this.order.originalDeductible.replace = null;
|
|
this.order.currentDeductible.repair = null;
|
|
this.order.currentDeductible.replace = null;
|
|
this.order.loadedFromDupeCheck = null;
|
|
this.order.loadedSessionClearedPreviousData = null;
|
|
this.order.availableVaps = null;
|
|
this.order.servicePackage = null;
|
|
this.order.carrierPhoneNumber = null;
|
|
this.order.customerPortalLoginToken = null;
|
|
this.order.loadedFromCookie = false;
|
|
this.order.visitedDuplicateCheckPage = false;
|
|
},
|
|
|
|
resetPolicy() {
|
|
this.order.policy.policyNumber = null;
|
|
this.order.policy.policyZipCode = null;
|
|
this.order.policy.dateOfLoss = null;
|
|
this.order.policy.damageCause = null;
|
|
this.order.policy.damageCity = null;
|
|
this.order.policy.damageState = null;
|
|
this.order.policy.vehicles = [];
|
|
this.order.policy.endorsements = [];
|
|
this.order.policy.endorsementQuestionAnswers = [];
|
|
this.order.policy.cvrgEndorsementCode = null;
|
|
this.order.policy.policyData = null;
|
|
this.order.policy.policyLookupErrorCode = 0;
|
|
this.order.policy.deductible.repair = null;
|
|
this.order.policy.deductible.replace = null;
|
|
},
|
|
|
|
resetPayment() {
|
|
this.order.payment.parentAccountNumber = 0;
|
|
this.order.payment.nextGenSettledAmount = 0;
|
|
this.order.payment.paymentMethod = null;
|
|
this.order.payment.paypalToken = null;
|
|
this.order.payment.creditCardToken.subscriptionId = null;
|
|
this.order.payment.creditCardToken.expMonth = null;
|
|
this.order.payment.creditCardToken.expYear = null;
|
|
this.order.payment.creditCardToken.cardType = null;
|
|
this.order.payment.creditCardToken.billToPostalCode = null;
|
|
this.order.payment.creditCardToken.billToFirstName = null;
|
|
this.order.payment.creditCardToken.billToLastName = null;
|
|
this.order.payment.creditCardToken.referenceNumber = null;
|
|
this.order.payment.creditCardToken.authCode = null;
|
|
this.order.payment.creditCardToken.transactionId = null;
|
|
this.order.payment.creditCardToken.transReferenceNumber = null;
|
|
this.order.payment.creditCardToken.lastFour = null;
|
|
},
|
|
|
|
resetCustomer() {
|
|
this.order.customer.emailAddress = null;
|
|
this.order.customer.firstName = null;
|
|
this.order.customer.lastName = null;
|
|
this.order.customer.address.city = null;
|
|
this.order.customer.address.state = null;
|
|
this.order.customer.address.zipCode = null;
|
|
this.order.customer.address.streetAddress = null;
|
|
this.order.customer.address.streetAddress2 = null;
|
|
},
|
|
|
|
resetContactInfo() {
|
|
this.order.contactInfo.homePhone = null;
|
|
this.order.contactInfo.alternativePhone = null;
|
|
this.order.contactInfo.servicePhone = null;
|
|
this.order.contactInfo.extension = null;
|
|
this.order.contactInfo.requestTextUpdates = false;
|
|
this.order.contactInfo.notesForTechnician = '';
|
|
},
|
|
|
|
resetVehicleState() {
|
|
this.order.vehicle.policyVehicleId = null;
|
|
this.order.vehicle.year = null;
|
|
this.order.vehicle.make = null;
|
|
this.order.vehicle.model = null;
|
|
this.order.vehicle.style = null;
|
|
this.order.vehicle.carId = null;
|
|
this.order.vehicle.category = null;
|
|
this.order.vehicle.vin = null;
|
|
this.order.vehicle.imageUrl = null;
|
|
this.order.vehicle.imageVifNumber = null;
|
|
this.order.vehicle.imageColor = null;
|
|
this.order.vehicle.registration.licensePlate = null;
|
|
this.order.vehicle.registration.state = null;
|
|
this.order.vehicle.registration.address = null;
|
|
this.order.vehicle.registration.city = null;
|
|
this.order.vehicle.registration.zipCode = null;
|
|
this.order.vehicle.registration.firstName = null;
|
|
this.order.vehicle.registration.lastName = null;
|
|
this.order.vehicle.isBigTruck = null;
|
|
this.order.vehicle.canSafeliteService = null;
|
|
|
|
if (this.isBailout && this.bailoutCode === bailoutCode.HeavyTruckVehicle) {
|
|
this.resetBailout();
|
|
}
|
|
},
|
|
|
|
resetGlassPartsState() {
|
|
this.order.lineItems.glassParts = null;
|
|
this.order.lineItems.supportingItems = [];
|
|
this.order.lineItems.vaps = null;
|
|
this.order.lineItems.feeItems = [];
|
|
this.order.lineItems.serverData = null;
|
|
this.order.damage.partQuestionAnswers = null;
|
|
this.order.damage.moldingQuestionAnswers = null;
|
|
this.order.damage.capabilityQuestionAnswers = null;
|
|
this.applicationUser.pageData[issPageValues.PART_QUESTIONS] = null;
|
|
this.applicationUser.pageData[issPageValues.VEHICLE_PARTS] = null;
|
|
this.applicationUser.pageData[issPageValues.MOLDING_QUESTIONS] = null;
|
|
this.applicationUser.pageData[issPageValues.CAPABILITY_QUESTIONS] = null;
|
|
},
|
|
resetSchedule() {
|
|
this.order.schedule.date = null;
|
|
this.order.schedule.startTime = null;
|
|
this.order.schedule.endTime = null;
|
|
this.order.schedule.routeCode = null;
|
|
this.order.schedule.jobMaxMinutes = null;
|
|
this.order.schedule.jobMinMinutes = null;
|
|
},
|
|
resetDamageState() {
|
|
this.order.damage.isRepair = null;
|
|
this.order.damage.numberOfChips = null;
|
|
this.order.damage.glassToReplace = null;
|
|
},
|
|
|
|
resetISSConfigState() {
|
|
this.issConfig.clientName = 'Generic Insurance';
|
|
this.issConfig.clientFullName = 'Generic Insurance';
|
|
this.issConfig.clientDisplayName = 'Generic Insurance';
|
|
this.issConfig.clientHeader = {};
|
|
this.issConfig.parentAccountNumber = 0;
|
|
this.issConfig.styleSheet = '';
|
|
this.issConfig.isCoverageEnabled = false;
|
|
this.issConfig.isAuthenticated = false;
|
|
this.issConfig.enableContinueFromCookie = false;
|
|
this.issConfig.enableTPAFlow = false;
|
|
this.issConfig.isClaimRegistrationRequired = false;
|
|
this.issConfig.successReturnURL = null;
|
|
this.issConfig.failureReturnURL = null;
|
|
this.issConfig.disabledFields.policyNumber = false;
|
|
this.issConfig.disabledFields.policyZipCode = false;
|
|
this.issConfig.disabledFields.dateOfLoss = false;
|
|
this.issConfig.siteType = null;
|
|
this.issConfig.enableNoCompQuote = false;
|
|
this.issConfig.billToAccountNumber = null;
|
|
},
|
|
|
|
disableKeyFields() {
|
|
this.issConfig.disabledFields.policyNumber = true;
|
|
this.issConfig.disabledFields.policyZipCode = true;
|
|
this.issConfig.disabledFields.dateOfLoss = true;
|
|
},
|
|
|
|
updateVehicleYear(year) {
|
|
if (this.order.vehicle.year !== year) {
|
|
this.resetVehicleState();
|
|
this.resetDamageAndDependencies();
|
|
|
|
this.order.vehicle.year = year;
|
|
}
|
|
},
|
|
|
|
updateVehicleMake(make) {
|
|
if (this.order.vehicle.make !== make) {
|
|
const { year } = this.order.vehicle;
|
|
|
|
this.resetVehicleState();
|
|
this.resetDamageAndDependencies();
|
|
|
|
this.order.vehicle.year = year;
|
|
this.order.vehicle.make = make;
|
|
}
|
|
},
|
|
|
|
updateVehicleModel(model) {
|
|
if (this.order.vehicle.model !== model) {
|
|
const { year } = this.order.vehicle;
|
|
const { make } = this.order.vehicle;
|
|
|
|
this.resetVehicleState();
|
|
this.resetDamageAndDependencies();
|
|
|
|
this.order.vehicle.year = year;
|
|
this.order.vehicle.make = make;
|
|
this.order.vehicle.model = model;
|
|
}
|
|
},
|
|
|
|
updateVehicleStyle(style) {
|
|
if (this.order.vehicle.style !== style) {
|
|
const { year } = this.order.vehicle;
|
|
const { make } = this.order.vehicle;
|
|
const { model } = this.order.vehicle;
|
|
|
|
this.resetVehicleState();
|
|
this.resetDamageAndDependencies();
|
|
|
|
this.order.vehicle.year = year;
|
|
this.order.vehicle.make = make;
|
|
this.order.vehicle.model = model;
|
|
this.order.vehicle.style = style;
|
|
}
|
|
},
|
|
|
|
updateEndorsementQuestionAnswers(answersArray) {
|
|
this.order.policy.endorsementQuestionAnswers = answersArray;
|
|
},
|
|
|
|
updateIsRepair(isRepair) {
|
|
this.order.damage.isRepair = isRepair;
|
|
},
|
|
|
|
updateNumberOfChips(numberOfChips) {
|
|
this.order.damage.numberOfChips = numberOfChips;
|
|
},
|
|
|
|
updateGlassToReplace(glassToReplace) {
|
|
this.order.damage.glassToReplace = glassToReplace;
|
|
},
|
|
|
|
updateGlassParts(partsData) {
|
|
this.order.lineItems.glassParts = partsData;
|
|
},
|
|
|
|
updateMoldingQuestionAnswers(answersArray) {
|
|
this.order.damage.moldingQuestionAnswers = answersArray;
|
|
},
|
|
|
|
updateCapabilityQuestionAnswers(answersArray) {
|
|
this.order.damage.capabilityQuestionAnswers = answersArray;
|
|
},
|
|
|
|
updatePartQuestionAnswers(answersArray) {
|
|
this.order.damage.partQuestionAnswers = answersArray;
|
|
},
|
|
|
|
updatePageData(pageData) {
|
|
this.applicationUser.pageData[pageData.page] = pageData.data;
|
|
},
|
|
updatePolicyData(welcomePageModel) {
|
|
this.order.policy.policyNumber = welcomePageModel?.policyNumber;
|
|
this.order.policy.policyZipCode = welcomePageModel?.policyZipCode;
|
|
this.order.policy.dateOfLoss = welcomePageModel?.dateOfLoss;
|
|
this.order.policy.damageCause = welcomePageModel?.damageCause;
|
|
this.order.policy.damageState = welcomePageModel?.damageState;
|
|
this.order.policy.damageCity = welcomePageModel?.damageCity;
|
|
this.order.policy.isDamageGlassOnly = welcomePageModel?.isDamageGlassOnly;
|
|
this.order.serviceLocation.zipCode = welcomePageModel?.policyZipCode;
|
|
this.updatePhoneNumbers({
|
|
home: welcomePageModel?.phoneNumber,
|
|
service: welcomePageModel?.phoneNumber,
|
|
extension: welcomePageModel?.extension
|
|
});
|
|
},
|
|
updatePolicyHolderDetails(customerQuestions) {
|
|
this.order.customer.address.streetAddress = customerQuestions.addressQuestions.streetAddress;
|
|
this.order.customer.address.streetAddress2 = customerQuestions.addressQuestions.streetAddress2;
|
|
this.order.customer.address.city = customerQuestions.addressQuestions.city;
|
|
this.order.customer.address.state = customerQuestions.addressQuestions.state;
|
|
this.order.customer.address.zipCode = customerQuestions.addressQuestions.zipCode;
|
|
this.order.customer.firstName = customerQuestions.firstName;
|
|
this.order.customer.lastName = customerQuestions.lastName;
|
|
this.order.customer.emailAddress = customerQuestions.email;
|
|
this.updatePhoneNumbers({
|
|
home: customerQuestions.phoneNumber,
|
|
service: customerQuestions.phoneNumber,
|
|
extension: customerQuestions.extension
|
|
});
|
|
this.order.serviceLocation.zipCode = customerQuestions.addressQuestions.zipCode;
|
|
},
|
|
updateIsSafeliteProvider(isSafelite) {
|
|
this.order.serviceLocation.IsSafeliteProvider = isSafelite;
|
|
},
|
|
updateDeductible(deductibleInfo) {
|
|
if (this.order.damage.isRepair) {
|
|
this.order.currentDeductible.repair = deductibleInfo.deductible;
|
|
} else {
|
|
this.order.currentDeductible.replace = deductibleInfo.deductible;
|
|
}
|
|
},
|
|
savePartQuestionAnswers(partQuestionAnswersArray) {
|
|
// if part question answers have changed, reset subsequent question answers
|
|
const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(this.order.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) {
|
|
this.resetServiceLocationAndDependencies();
|
|
|
|
this.updateGlassParts(null);
|
|
this.updateMoldingQuestionAnswers(null);
|
|
this.updateCapabilityQuestionAnswers(null);
|
|
this.updateSupportingItems(null);
|
|
this.updateVaps(null);
|
|
this.updateServicePackage(null);
|
|
|
|
this.updatePageData({ page: issPageValues.VEHICLE_PARTS, data: null });
|
|
this.updatePageData({ page: issPageValues.MOLDING_QUESTIONS, data: null });
|
|
this.updatePageData({ page: issPageValues.CAPABILITY_QUESTIONS, data: null });
|
|
}
|
|
|
|
// Save new values
|
|
this.updatePartQuestionAnswers(partQuestionAnswersArray);
|
|
},
|
|
saveMoldingQuestionAnswers(moldingQuestionAnswersArray) {
|
|
const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(this.order.damage.moldingQuestionAnswers, 'result');
|
|
const sortedMoldingQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(moldingQuestionAnswersArray, 'result');
|
|
const haveMoldingQuestionAnswersChanged = sortedPreviousResultsArray?.length !== sortedMoldingQuestionAnswersArray.length
|
|
|| !sortedPreviousResultsArray?.every((x, i) => x.result === sortedMoldingQuestionAnswersArray[i].result);
|
|
|
|
if (haveMoldingQuestionAnswersChanged) {
|
|
this.resetServiceLocationAndDependencies();
|
|
|
|
this.updateGlassParts(null);
|
|
this.updateSupportingItems(null);
|
|
this.updateCapabilityQuestionAnswers(null);
|
|
this.updatePageData({ page: issPageValues.CAPABILITY_QUESTIONS, data: null });
|
|
}
|
|
|
|
// Save new values
|
|
this.updateMoldingQuestionAnswers(moldingQuestionAnswersArray);
|
|
},
|
|
saveCapabilityQuestionAnswers(capabilityQuestionAnswersArray) {
|
|
const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(this.order.damage.capabilityQuestionAnswers, 'result');
|
|
const sortedCapabilityQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(capabilityQuestionAnswersArray, 'result');
|
|
const haveCapabilityQuestionAnswersChanged = sortedPreviousResultsArray?.length !== sortedCapabilityQuestionAnswersArray.length
|
|
|| !sortedPreviousResultsArray?.every((x, i) => x.result === sortedCapabilityQuestionAnswersArray[i].result);
|
|
|
|
if (haveCapabilityQuestionAnswersChanged) {
|
|
this.resetServiceLocationAndDependencies();
|
|
|
|
this.updateGlassParts(null);
|
|
this.updateSupportingItems(null);
|
|
}
|
|
|
|
// Save new values
|
|
this.updateCapabilityQuestionAnswers(capabilityQuestionAnswersArray);
|
|
},
|
|
|
|
// Tax order actions
|
|
async getTaxOrderItems(pricedLineItems) {
|
|
const { order } = this;
|
|
const { serviceLocation } = order;
|
|
const { appointmentType } = serviceLocation;
|
|
const serviceLocationCity = serviceLocation.city;
|
|
const serviceLocationState = serviceLocation.state;
|
|
const serviceLocationZipCode = serviceLocation.zipCode;
|
|
const lineItemServerData = this.order.lineItems.serverData;
|
|
|
|
const isMobileApt = appointmentType === AppointmentTypeStrings.MOBILE
|
|
|| appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
|
|
|
|
const retPricedLineItems = await globalMethods.callHttpClient({
|
|
method: endpoints.TaxOrderItems.method,
|
|
endpoint: endpoints.TaxOrderItems.url,
|
|
payload: {
|
|
ParentAccountNumber: this.order.parentAccountNumber,
|
|
BillToAccountNumber: this.billToAccountNumber,
|
|
ProviderNumber: this.providerNumber,
|
|
AppointmentType: appointmentType,
|
|
PricedLineItems: getLineItemsFlattened(pricedLineItems),
|
|
ServiceLocation: {
|
|
City: isMobileApt ? serviceLocationCity : null,
|
|
State: isMobileApt ? serviceLocationState : null,
|
|
ZipCode: isMobileApt ? serviceLocationZipCode : null
|
|
},
|
|
ServerData: lineItemServerData || ''
|
|
}
|
|
}).then((response) => {
|
|
this.order.lineItems.serverData = response.data.serverData;
|
|
return addTaxesToPricedLineItems(pricedLineItems, response.data.taxedLineItems);
|
|
});
|
|
|
|
return retPricedLineItems;
|
|
},
|
|
addEventToBus(event) {
|
|
this.applicationUser.eventBus.push(event);
|
|
},
|
|
removeEventFromBus(eventData) {
|
|
const matchedEvent = this.applicationUser.eventBus.find(({ category, subCategory }) => category === eventData.category && subCategory === eventData.subCategory);
|
|
const itemIndex = this.applicationUser.eventBus.indexOf(matchedEvent);
|
|
|
|
// If the item exists, remove it.
|
|
if (itemIndex > -1) {
|
|
this.applicationUser.eventBus.splice(itemIndex, 1);
|
|
}
|
|
},
|
|
|
|
// populate initial state
|
|
populateInitialState(forceReset) {
|
|
if (!sessionStorage.getItem(storeId) || forceReset) {
|
|
this.$state = getDefaultState();
|
|
this.resetSubmittedOrder();
|
|
}
|
|
},
|
|
|
|
// Location API Actions
|
|
getAlertReasonsByCtu(ctu) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetAlertReasons.method,
|
|
endpoint: `${endpoints.GetAlertReasons.url}/${ctu}`,
|
|
payload: {}
|
|
});
|
|
},
|
|
|
|
// Schedule Actions
|
|
saveSchedule(scheduleInfo) {
|
|
this.updateSchedule(scheduleInfo);
|
|
},
|
|
updateSchedule(scheduleInfo) {
|
|
if (scheduleInfo) {
|
|
this.order.schedule.date = scheduleInfo.date;
|
|
this.order.schedule.startTime = scheduleInfo.startTime;
|
|
this.order.schedule.endTime = scheduleInfo.endTime;
|
|
this.order.schedule.routeCode = scheduleInfo.routeCode;
|
|
this.order.schedule.jobMaxMinutes = scheduleInfo.jobMaxMinutes;
|
|
this.order.schedule.jobMinMinutes = scheduleInfo.jobMinMinutes;
|
|
}
|
|
},
|
|
// Analytics Actions
|
|
logExperimentExposure(pageName, experiment) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LogExperimentExposureIfAssigned.method,
|
|
endpoint: endpoints.LogExperimentExposureIfAssigned.url,
|
|
payload: {
|
|
experimentForLogging: {
|
|
userId: getUserIdValue(),
|
|
deviceId: getDeviceIdValue(),
|
|
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: getSessionKeyValue(),
|
|
pageName
|
|
}
|
|
},
|
|
bailoutOnError: false
|
|
});
|
|
},
|
|
logExperimentIfExists(pageName, universe) {
|
|
const experiment = this.applicationUser.experiments.find((e) => e.universeName === universe);
|
|
if (experiment !== undefined) {
|
|
void this.logExperimentExposure(pageName, experiment)
|
|
.catch((error) => {
|
|
console.error(`Failed to log experiment exposure: ${error?.data ?? error}`);
|
|
});
|
|
}
|
|
},
|
|
async logPageView({ userId, sessionKey, pageName, referralSequenceNumber, parentAccountNumber, sessionId, action, event, shouldUseSessionId, experimentsForUser }) {
|
|
const payload = {
|
|
userId,
|
|
sessionKey,
|
|
sessionId,
|
|
pageName,
|
|
referralSequenceNumber,
|
|
parentAccountNumber,
|
|
applicationName: applicationConfig.APPLICATION_NAME,
|
|
action,
|
|
event,
|
|
shouldUseSessionId,
|
|
experimentsForUser
|
|
};
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LogPageView.method,
|
|
endpoint: endpoints.LogPageView.url,
|
|
payload,
|
|
logApiCall: false,
|
|
bailoutOnError: false
|
|
}).then(
|
|
(response) => response,
|
|
(error) => {
|
|
console.log(`Analytics Service Error: ${error.data}`);
|
|
}
|
|
);
|
|
},
|
|
async logCustomEvent({ userId, sessionKey, pageName, sessionId, category, action, label, value, shouldUseSessionId, experimentsForUser }) {
|
|
if (pageName == null || pageName.length === 0) { pageName = 'none'; }
|
|
|
|
const payload = {
|
|
userId,
|
|
sessionKey,
|
|
sessionId,
|
|
pageName,
|
|
applicationName: applicationConfig.APPLICATION_NAME,
|
|
category,
|
|
action,
|
|
label,
|
|
value,
|
|
shouldUseSessionId,
|
|
experimentsForUser
|
|
};
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LogCustomEvent.method,
|
|
endpoint: endpoints.LogCustomEvent.url,
|
|
payload,
|
|
logApiCall: false,
|
|
bailoutOnError: false
|
|
}).then(
|
|
(response) => response,
|
|
(error) => {
|
|
console.log(`Analytics Service Error: ${error.data}`);
|
|
}
|
|
);
|
|
},
|
|
logMobileFirstExperimentExposure() {
|
|
this.logExperimentIfExists(issPageValues.SCHEDULE_PAGE, experimentUniverses.ISS_MOBILE_FIRST_APPOINTMENTS);
|
|
},
|
|
logWelcomePageExperiments(issPage) {
|
|
this.logExperimentIfExists(issPage, experimentUniverses.ISS_FEATURETOGGLE_AREFEES_HIDDEN);
|
|
this.logExperimentIfExists(issPage, experimentUniverses.ISS_FEATURETOGGLE_AREFEES_OVERRIDDEN);
|
|
},
|
|
async initializeSession({ userId, sessionId, userAgent, referrer }) {
|
|
const payload = {
|
|
applicationName: applicationConfig.APPLICATION_NAME,
|
|
userId,
|
|
deviceId: userId,
|
|
sessionId,
|
|
userAgent,
|
|
operatorId: 'WEB',
|
|
userName: 'SafeliteISS',
|
|
referrer
|
|
};
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.InitializeSession.method,
|
|
endpoint: endpoints.InitializeSession.url,
|
|
payload,
|
|
logApiCall: false,
|
|
bailoutOnError: false
|
|
}).then(
|
|
(response) => response,
|
|
(error) => {
|
|
console.log(`Analytics Service Error: ${error.data}`);
|
|
}
|
|
);
|
|
},
|
|
|
|
updateLastPageVisited(lastPageVisited) {
|
|
this.applicationUser.lastPageVisited = lastPageVisited;
|
|
},
|
|
|
|
updateExperiments(experiments) {
|
|
this.applicationUser.experiments = experiments;
|
|
},
|
|
updateTriggeredSiteEntry(wasSiteEntryTriggered) {
|
|
this.applicationUser.triggeredSiteEntry = wasSiteEntryTriggered;
|
|
},
|
|
|
|
// TODO: Shouldn't this be async?
|
|
logDigitalConsumer(
|
|
{
|
|
deviceId,
|
|
sessionId,
|
|
actionName,
|
|
referralSequenceNumber,
|
|
referralNumber,
|
|
workOrderId,
|
|
workOrderNumber,
|
|
conceptVariation,
|
|
isConceptExposed,
|
|
}
|
|
) {
|
|
var payload = {
|
|
sessionId: sessionId,
|
|
deviceId: deviceId,
|
|
actionName: actionName ?? "",
|
|
referralSequenceNumber: referralSequenceNumber ?? "",
|
|
referralNumber: referralNumber ?? "",
|
|
applicationName: isMobileDevice() ? "ISS Mobile" : "ISS",
|
|
workOrderId: workOrderId ?? "",
|
|
workOrderNumber: workOrderNumber ?? "",
|
|
conceptVariation: conceptVariation,
|
|
isConceptExposed: isConceptExposed,
|
|
};
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LogDigitalConsumer.method,
|
|
endpoint: endpoints.LogDigitalConsumer.url,
|
|
payload,
|
|
logApiCall: false,
|
|
bailoutOnError: false
|
|
}).then(
|
|
(response) => response,
|
|
(error) => {
|
|
console.log(`Analytics Service Error: ${error.data}`);
|
|
}
|
|
);
|
|
},
|
|
|
|
// TODO: Shouldn't this be async?
|
|
logIssSessionData(
|
|
{
|
|
currentPage,
|
|
sid,
|
|
deviceId,
|
|
issSessionId,
|
|
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,
|
|
subTotalPrice,
|
|
totalPrice,
|
|
userAgent,
|
|
cashPriceSubTotal,
|
|
}
|
|
) {
|
|
var payload = {
|
|
currentPage: currentPage,
|
|
sid: sid,
|
|
deviceId: deviceId,
|
|
fmgSessionId: issSessionId,
|
|
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,
|
|
subTotalPrice: subTotalPrice,
|
|
totalPrice: totalPrice,
|
|
userAgent: userAgent,
|
|
cashPriceSubTotal: cashPriceSubTotal,
|
|
billToAccountNumber: billToAccountNumber,
|
|
};
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LogIssSessionData.method,
|
|
endpoint: endpoints.LogIssSessionData.url,
|
|
payload,
|
|
logApiCall: false,
|
|
bailoutOnError: false
|
|
}).then(
|
|
(response) => response,
|
|
(error) => {
|
|
console.log(`Analytics Service Error: ${error.data}`);
|
|
}
|
|
);
|
|
},
|
|
|
|
updateContactInfo(contactInfo) {
|
|
this.order.customer.firstName = contactInfo?.firstName ?? this.order.customer.firstName;
|
|
this.order.customer.lastName = contactInfo?.lastName ?? this.order.customer.lastName;
|
|
this.order.customer.emailAddress = contactInfo?.emailAddress ?? this.order.customer.emailAddress;
|
|
|
|
this.order.contactInfo.requestTextUpdates = contactInfo?.requestTextUpdates ?? false;
|
|
this.order.contactInfo.notesForTechnician = contactInfo?.notesForTechnician ?? '';
|
|
},
|
|
|
|
updatePhoneNumbers(phoneNumbers) {
|
|
const contact = this.order.contactInfo;
|
|
contact.homePhone = phoneNumbers.home !== undefined ? phoneNumbers.home : contact.homePhone;
|
|
contact.alternativePhone = phoneNumbers.alternative !== undefined ? phoneNumbers.alternative : contact.alternativePhone;
|
|
contact.servicePhone = phoneNumbers.service !== undefined ? phoneNumbers.service : contact.servicePhone;
|
|
contact.extension = phoneNumbers.extension !== undefined ? phoneNumbers.extension : contact.extension;
|
|
},
|
|
|
|
GetExperimentsByUser(userId) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetExperimentsByUser.method,
|
|
endpoint: `${endpoints.GetExperimentsByUser.url}/${userId}`,
|
|
payload: {}
|
|
});
|
|
},
|
|
|
|
async runExperimentsForTrigger({ deviceId, triggerEvent, triggerValue }) {
|
|
if (triggerEvent === experimentTriggers.SITE_ENTRY) {
|
|
this.updateTriggeredSiteEntry(true);
|
|
}
|
|
|
|
const payload = {
|
|
applicationName: applicationConfig.APPLICATION_NAME,
|
|
deviceId,
|
|
triggerEvent,
|
|
triggerValue,
|
|
experimentOrder: this.experimentOrder
|
|
};
|
|
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.RunExperimentsForTrigger.method,
|
|
endpoint: endpoints.RunExperimentsForTrigger.url,
|
|
payload: payload,
|
|
bailoutOnError: false
|
|
});
|
|
|
|
this.updateExperiments(response.data.experiments);
|
|
},
|
|
|
|
async validateZip({ zip }) {
|
|
try {
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.ValidateZip.method,
|
|
endpoint: endpoints.ValidateZip.url(zip)
|
|
});
|
|
const zipInfo = response.data;
|
|
if (zipInfo?.isValid === true) {
|
|
this.order.serviceLocation.zipCodeCtu = zipInfo.zipCodeCtu;
|
|
this.order.serviceLocation.defaultProviderNumber = zipInfo.providerNumber;
|
|
this.order.serviceLocation.state = zipInfo.state;
|
|
return Promise.resolve(zipInfo);
|
|
}
|
|
|
|
return Promise.reject(new Error('Invalid Zip Info'));
|
|
} catch (e) {
|
|
return Promise.reject(e);
|
|
}
|
|
},
|
|
|
|
async validateMobileZip({ zip }) {
|
|
const damageType = this.order.damage.isRepair ? 'Repair' : 'Replace';
|
|
try {
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.ValidateZip.method,
|
|
endpoint: endpoints.ValidateMobileZip.url(zip, damageType)
|
|
});
|
|
const zipInfo = response.data;
|
|
if (zipInfo?.isValid === true) {
|
|
return Promise.resolve(zipInfo);
|
|
}
|
|
|
|
return Promise.reject(new Error('Invalid Zip Info'));
|
|
} catch (e) {
|
|
return Promise.reject(e);
|
|
}
|
|
},
|
|
|
|
async getBillToInfo(componentProviderNumber = null) {
|
|
const providerNumber = componentProviderNumber || this.providerNumber;
|
|
if (!providerNumber) {
|
|
return;
|
|
}
|
|
|
|
const { order, issConfig } = this;
|
|
const params = new URLSearchParams({
|
|
parentAccountNumber: order.parentAccountNumber.toString(),
|
|
providerNumber,
|
|
typeOfClaim: 'GLASS ONLY',
|
|
lineOfBusiness: 'PERSONAL',
|
|
isItac: this.isITAC
|
|
});
|
|
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.GetBillToInfo.method,
|
|
endpoint: `${endpoints.GetBillToInfo.url}?${params.toString()}`,
|
|
bailoutOnError: false
|
|
});
|
|
|
|
const billToInfo = response.data;
|
|
issConfig.billToAccountNumber = billToInfo.toString();
|
|
},
|
|
|
|
async validateClientTag(clientTag) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.ValidateClientTag.method,
|
|
endpoint: `${endpoints.ValidateClientTag.url}/${clientTag}`
|
|
});
|
|
},
|
|
|
|
async validateClientSignature(clientTag, token, signature) {
|
|
const payload = {
|
|
clientTag,
|
|
token,
|
|
signature
|
|
};
|
|
|
|
return await globalMethods.callHttpClient({
|
|
method: endpoints.ValidateClientSignature.method,
|
|
endpoint: endpoints.ValidateClientSignature.url,
|
|
payload
|
|
});
|
|
},
|
|
|
|
saveRegistrationAddressLookup({ isSelectedGlassAvailableForVehicle, vehicleInfo, registrationInfo }) {
|
|
// Reset dependent state when changing
|
|
if
|
|
(
|
|
registrationInfo?.address !== this.order.vehicle.registration?.address
|
|
|| registrationInfo?.city !== this.order.vehicle.registration?.city
|
|
|| registrationInfo?.state !== this.order.vehicle.registration?.state
|
|
|| registrationInfo?.zipCode !== this.order.vehicle.registration?.zipCode
|
|
|| registrationInfo?.firstName !== this.order.vehicle.registration?.firstName
|
|
|| registrationInfo?.lastName !== this.order.vehicle.registration?.lastName
|
|
) {
|
|
if (!isSelectedGlassAvailableForVehicle) {
|
|
this.resetDamageState();
|
|
this.resetGlassPartsState();
|
|
}
|
|
|
|
// Save new values
|
|
this.updateRegistration(registrationInfo);
|
|
}
|
|
|
|
if (vehicleInfo) {
|
|
this.updateVehicle(vehicleInfo);
|
|
}
|
|
},
|
|
saveVin({ isSelectedGlassAvailableForVehicle, vehicleInfo }) {
|
|
// Reset dependent state when changing
|
|
if (vehicleInfo.vin !== this.order.vehicle.vin) {
|
|
this.resetRegistrationAndDependencies();
|
|
|
|
if (!isSelectedGlassAvailableForVehicle) {
|
|
this.resetDamageState();
|
|
this.resetGlassPartsState();
|
|
}
|
|
|
|
// Save new values
|
|
this.updateVehicle(vehicleInfo);
|
|
}
|
|
},
|
|
saveRegistrationLicensePlateLookup({ isSelectedGlassAvailableForVehicle, vehicleInfo, registrationInfo }) {
|
|
// Reset dependent state when changing
|
|
if (registrationInfo?.licensePlate !== this.order.vehicle.registration?.licensePlate
|
|
|| registrationInfo?.state !== this.order.vehicle.registration?.state) {
|
|
this.resetRegistrationAndDependencies();
|
|
|
|
if (!isSelectedGlassAvailableForVehicle) {
|
|
// Dependencies already cleared in above statement
|
|
this.resetDamageState();
|
|
this.resetGlassPartsState();
|
|
}
|
|
|
|
// Save new values
|
|
this.updateVehicle(vehicleInfo);
|
|
}
|
|
|
|
this.updateRegistration(registrationInfo);
|
|
},
|
|
|
|
setBailout(bailoutData) {
|
|
const params = new URL(document.location.toString()).searchParams;
|
|
const currentPage = params.get('issPage');
|
|
|
|
this.updatePageData({
|
|
page: issPageValues.BAILOUT_PAGE,
|
|
data: {
|
|
url: window.location.href,
|
|
page: currentPage || 'Unknown Page',
|
|
bailoutCode: bailoutData.code,
|
|
errorMessage: bailoutData.message,
|
|
submit: false
|
|
}
|
|
});
|
|
},
|
|
|
|
setBailoutContactInfo(contact) {
|
|
this.order.customer.firstName = contact.firstName;
|
|
this.order.customer.lastName = contact.lastName;
|
|
this.order.customer.emailAddress = contact.email;
|
|
this.updatePhoneNumbers({
|
|
home: contact.phoneNumber,
|
|
service: contact.phoneNumber
|
|
});
|
|
this.pageData(issPageValues.BAILOUT_PAGE).submit = true;
|
|
},
|
|
|
|
resetRegistrationAndDependencies() {
|
|
this.resetRegistrationState();
|
|
this.resetGlassPartsState();
|
|
this.updateVaps(null);
|
|
this.updateServicePackage(null);
|
|
},
|
|
|
|
resetDamageAndDependencies() {
|
|
this.resetDamageState();
|
|
this.resetGlassPartsState();
|
|
this.updateVaps(null);
|
|
this.updateServicePackage(null);
|
|
},
|
|
|
|
resetPartsAndDependencies() {
|
|
this.resetGlassPartsState();
|
|
this.updateVaps(null);
|
|
this.updateServicePackage(null);
|
|
|
|
this.resetServiceLocationAndDependencies();
|
|
},
|
|
|
|
resetServiceLocation() {
|
|
this.order.serviceLocation.state = null;
|
|
this.order.serviceLocation.zipCode = null;
|
|
this.order.serviceLocation.zipCodeCtu = null;
|
|
this.order.serviceLocation.defaultProviderNumber = null;
|
|
this.order.serviceLocation.appointmentType = null;
|
|
this.order.serviceLocation.IsSafeliteProvider = null;
|
|
this.resetServiceLocationProvider();
|
|
this.resetServiceLocationMobileAddress();
|
|
},
|
|
|
|
resetPageFields() {
|
|
this.resetOrder();
|
|
this.resetCustomer();
|
|
this.resetPolicy();
|
|
this.resetPayment();
|
|
this.resetContactInfo();
|
|
this.resetVehicleState();
|
|
this.resetDamageState();
|
|
this.resetGlassPartsState();
|
|
this.resetInsurance();
|
|
this.resetServiceLocation();
|
|
this.resetSchedule();
|
|
this.resetBailout();
|
|
this.resetSubmittedOrder();
|
|
},
|
|
savePaymentMethodChoice(paymentMethod) {
|
|
this.order.payment.paymentMethod = paymentMethod;
|
|
},
|
|
|
|
getPaymentSignature() {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetPaymentSignature.method,
|
|
endpoint: endpoints.GetPaymentSignature.url
|
|
});
|
|
},
|
|
async initializeAdyenPayment(requestBody) {
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.InitializeAdyenPayment.method,
|
|
endpoint: endpoints.InitializeAdyenPayment.url,
|
|
payload: requestBody,
|
|
logApiCall: true
|
|
});
|
|
return response.data;
|
|
},
|
|
async getAdyenSessionResult(paymentSessionRequest) {
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.GetAdyenSessionResult.method,
|
|
endpoint: endpoints.GetAdyenSessionResult.url,
|
|
payload: paymentSessionRequest,
|
|
logApiCall: true
|
|
});
|
|
return response.data;
|
|
},
|
|
|
|
hasSubmittedOrder() {
|
|
return window.sessionStorage.getItem(webStorageConstants.SUBMITTED_ORDER) !== null;
|
|
},
|
|
|
|
getSubmittedOrder() {
|
|
return JSON.parse(window.sessionStorage.getItem(webStorageConstants.SUBMITTED_ORDER));
|
|
},
|
|
|
|
async createSubmittedOrder(submitType) {
|
|
if (this.hasSubmittedOrder()) {
|
|
return;
|
|
}
|
|
await this.getCarrierAccountInfo();
|
|
const submittedOrder = this.order;
|
|
const { experiments } = this.applicationUser;
|
|
const { issConfig, hasRecalibrationPart } = this;
|
|
|
|
submittedOrder.isUnverified = this.isUnverified;
|
|
submittedOrder.isVerified = this.isVerified;
|
|
submittedOrder.submitType = submitType;
|
|
submittedOrder.payment.isPayInAdvance = this.isPayInAdvance;
|
|
submittedOrder.hasRecalibrationPart = hasRecalibrationPart;
|
|
|
|
// set to sessionStorage
|
|
window.sessionStorage.setItem(webStorageConstants.SUBMITTED_ORDER, JSON.stringify(submittedOrder));
|
|
|
|
// clear vuex
|
|
this.resetState();
|
|
|
|
// delete cookie
|
|
deleteISSCookie();
|
|
|
|
// restore issConfig
|
|
this.issConfig = issConfig;
|
|
// restore user's experiments
|
|
this.applicationUser.experiments = experiments;
|
|
},
|
|
|
|
resetSubmittedOrder() {
|
|
// clear from sessionStorage
|
|
window.sessionStorage.removeItem(webStorageConstants.SUBMITTED_ORDER);
|
|
},
|
|
},
|
|
persist: {
|
|
// Default is localStorage, but sessionStorage is used here to ensure state is cleared when the browser tab is closed, preventing potential issues with stale data on return visits.
|
|
storage: sessionStorage
|
|
}
|
|
});
|
|
|
|
// Private Functions
|
|
|
|
function getHasRecalibrationPartOnOrder(state) {
|
|
return getHasRecalibrationPart(state.order.lineItems);
|
|
}
|
|
|
|
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 addPricesToLineItems(lineItems, pricingLineItems) {
|
|
const partOffset = {};
|
|
|
|
lineItems.forEach((lineItem) => {
|
|
if (lineItem.childParts) {
|
|
addPricesToLineItems(lineItem.childParts, pricingLineItems);
|
|
}
|
|
const { partNumber } = lineItem;
|
|
|
|
const pricedIndex = findLineItemIndex(pricingLineItems, partNumber, partOffset[partNumber] ?? 0);
|
|
if (pricedIndex !== -1) {
|
|
const pricedLineItem = pricingLineItems[pricedIndex];
|
|
lineItem.laborAmount = pricedLineItem.laborAmount;
|
|
lineItem.sellingPrice = pricedLineItem.sellingPrice;
|
|
lineItem.kitPrice = pricedLineItem.kitPrice;
|
|
partOffset[partNumber] = pricedIndex + 1;
|
|
}
|
|
});
|
|
return lineItems;
|
|
}
|
|
|
|
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 convertGlassPieceToBackEndCompatibleFormat(glassPieces) {
|
|
return glassPieces.map((glassPiece) => ({
|
|
location: glassPiece.glassLocation,
|
|
name: glassPiece.glassName
|
|
}));
|
|
}
|
|
|
|
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 provisionalTriggersToString(provisionalTriggers) {
|
|
return `ProvisionalTriggers:${provisionalTriggers.join(',')}`;
|
|
}
|
|
|
|
function setClearOnSubmit(lineItemArray, shouldClearOnSubmit) {
|
|
const retArray = [];
|
|
if (lineItemArray && lineItemArray.length > 0) {
|
|
lineItemArray.forEach((part) => {
|
|
const newPart = { ...part };
|
|
newPart.clearOnSubmit = shouldClearOnSubmit;
|
|
|
|
retArray.push(newPart);
|
|
});
|
|
}
|
|
|
|
return retArray;
|
|
}
|