add service location / schedule resets similar to FMG fix weird loader scroll bar thing on datepicker
2136 lines
95 KiB
JavaScript
2136 lines
95 KiB
JavaScript
/* eslint-disable no-use-before-define */
|
|
/* eslint-disable max-len */
|
|
import { defineStore } from 'pinia';
|
|
import { endpoints } from '@/constants/endpoints';
|
|
// eslint-disable-next-line import/no-cycle
|
|
import { getDateForSavedSessionTimeout } from '@/helpers/session-helper';
|
|
// eslint-disable-next-line import/no-cycle
|
|
import globalMethods from '@/global-methods';
|
|
import { experimentTriggers } from '@/constants/experiments';
|
|
import applicationConfig from '@/constants/application-config';
|
|
import issPageValues from '@/router/router-constants/issPage-values';
|
|
import damageLocationsSelected from '@/constants/damage-locations-selected';
|
|
import coverageStatuses from '@/constants/coverage-statuses';
|
|
import { deepEqual } from '@/helpers/object-helper';
|
|
import { AppointmentTypeStrings, PREMIUM_FEE_PART_TYPE } from '@/constants/schedule-constants';
|
|
import getDateDifferenceInDays from '@/helpers/date-helper';
|
|
|
|
const storeId = 'main';
|
|
|
|
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(',')}`;
|
|
}
|
|
|
|
const getDefaultState = () => ({
|
|
order: {
|
|
vehicle: {
|
|
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
|
|
}
|
|
},
|
|
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,
|
|
policyLookupSuccessful: null,
|
|
noCoverage: 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,
|
|
},
|
|
isITAC: null,
|
|
vehicles: [],
|
|
endorsements: [],
|
|
endorsementQuestionAnswers: null
|
|
},
|
|
customer: {
|
|
address: {
|
|
streetAddress: null,
|
|
streetAddress2: null,
|
|
city: null,
|
|
state: null,
|
|
zipCode: null
|
|
},
|
|
firstName: null,
|
|
lastName: null,
|
|
emailAddress: null,
|
|
phoneNumber: null
|
|
},
|
|
serviceLocation: {
|
|
address: null,
|
|
address2: null,
|
|
city: null,
|
|
state: null,
|
|
zipCode: null,
|
|
zipCodeCtu: null,
|
|
appointmentType: null,
|
|
isVehicleProtected: null,
|
|
provider: {
|
|
providerNumber: null,
|
|
address: {
|
|
streetAddress: null,
|
|
city: null,
|
|
state: null,
|
|
zipCode: null,
|
|
zipCodeCtu: null
|
|
}
|
|
}
|
|
},
|
|
lineItems: {
|
|
glassParts: null,
|
|
otherParts: null,
|
|
supportingItems: null,
|
|
vaps: null
|
|
},
|
|
payment: {
|
|
insuranceCoverage: {
|
|
isVerified: false,
|
|
coverageStatus: coverageStatuses.PENDING,
|
|
claimNumber: null
|
|
},
|
|
parentAccountNumber: 0
|
|
},
|
|
contactInfo: {
|
|
firstName: null,
|
|
lastName: null,
|
|
emailAddress: null,
|
|
phoneNumber: null,
|
|
requestTextUpdates: false,
|
|
notesForTechnician: ''
|
|
},
|
|
schedule: {
|
|
date: null,
|
|
startTime: null,
|
|
endTime: null,
|
|
routeCode: null,
|
|
jobMaxMinutes: null,
|
|
jobMinMinutes: null
|
|
},
|
|
referralNumber: null,
|
|
referralDate: null,
|
|
referralCorrelationId: '00000000-0000-0000-0000-000000000000',
|
|
referralSequenceNumber: null,
|
|
eon: null,
|
|
workOrderNumber: null,
|
|
originalDeductible: null,
|
|
currentDeductible: null
|
|
},
|
|
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
|
|
},
|
|
issConfig: {
|
|
clientName: 'Generic Insurance', // this is the default and will be overriden by the client's name
|
|
clientDisplayName: 'Generic Insurance', // this is the default and will be overridden by the client's name or client display name.
|
|
styleSheet: '', // Stylesheet used by the client.
|
|
parentAccountNumber: 0, // Parent account number used by the client.
|
|
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.
|
|
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
|
|
}
|
|
}
|
|
});
|
|
|
|
export const state = getDefaultState();
|
|
|
|
export const useMainStore = defineStore({
|
|
id: storeId,
|
|
state: () => state,
|
|
getters: {
|
|
hasRecalibrationPart: (state) => getHasRecalibrationPart(state),
|
|
vehicle: (state) => state.order.vehicle,
|
|
damage: (state) => state.order.damage,
|
|
lineItems: (state) => state.order.lineItems,
|
|
payment: (state) => state.order.payment,
|
|
policy: (state) => state.order.policy,
|
|
hasAnyNonWindshieldGlassParts: (state) => !state.order.policy.isDamageGlassOnly,
|
|
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,
|
|
isClaimRegistrationRequired: (state) => state.issConfig.isClaimRegistrationRequired,
|
|
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.contactInfo.firstName ?? s.order.customer.firstName,
|
|
lastName: s.order.contactInfo.lastName ?? s.order.customer.lastName,
|
|
emailAddress: s.order.contactInfo.emailAddress ?? s.order.customer.emailAddress,
|
|
phoneNumber: s.order.contactInfo.phoneNumber ?? s.order.customer.phoneNumber,
|
|
requestTextUpdates: s.order.contactInfo.requestTextUpdates ?? false,
|
|
notesForTechnician: s.order.contactInfo.notesForTechnician
|
|
}),
|
|
experimentOrder: (state) => ({
|
|
issVehicleYear: state.order.vehicle.year,
|
|
issVehicleMake: state.order.vehicle.make,
|
|
issVehicleModel: state.order.vehicle.model,
|
|
issVehicleStyle: state.order.vehicle.style,
|
|
issIsRepair: state.order.damage.isRepair,
|
|
issNumberOfChips: state.order.damage.numberOfChips,
|
|
issCarId: state.order.vehicle.carId,
|
|
issServiceCity: state.order.serviceLocation.city,
|
|
issServiceState: state.order.serviceLocation.state,
|
|
issServiceZipCode: state.order.serviceLocation.zipCode,
|
|
issParentAccountNumber: state.order.accountNumber,
|
|
issIsCoverageVerified: state.order.payment.insuranceCoverage.isVerified,
|
|
issHasRecalibrationPart: getHasRecalibrationPart(state),
|
|
issSelectedMultiGlass: state.order.damage.glassToReplace?.length > 1,
|
|
issSelectedWindshieldGlass: getNonFalseValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, 'glassLocation')
|
|
.includes(damageLocationsSelected.WINDSHIELD),
|
|
issSelectedBackGlass: getNonFalseValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, 'glassLocation')
|
|
.includes(damageLocationsSelected.REAR),
|
|
issSelectedDriverSideGlass: getNonFalseValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, 'glassLocation')
|
|
.includes(damageLocationsSelected.DRIVER),
|
|
issSelectedPassengerSideGlass: getNonFalseValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, 'glassLocation')
|
|
.includes(damageLocationsSelected.PASSENGER),
|
|
issOrderPartNumbers: [
|
|
...getNonFalseValuesOfPropertyInArrayOfObjects(
|
|
state.order.lineItems.glassParts,
|
|
'partNumber'
|
|
),
|
|
...getNonFalseValuesOfPropertyInArrayOfObjects(
|
|
state.order.lineItems.otherParts,
|
|
'partNumber'
|
|
)
|
|
],
|
|
issOrderPartTypes: [
|
|
...getNonFalseValuesOfPropertyInArrayOfObjects(
|
|
state.order.lineItems.glassParts,
|
|
'recalibrationType'
|
|
),
|
|
...getNonFalseValuesOfPropertyInArrayOfObjects(
|
|
state.order.lineItems.otherParts,
|
|
'recalibrationType'
|
|
)
|
|
]
|
|
}),
|
|
experimentSettings: (state) => state.applicationUser.experiments
|
|
.map((x) => x.settings)
|
|
.reduce((r, c) => Object.assign(r, c), {}) ?? {}
|
|
},
|
|
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() {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetVehicleModels.method,
|
|
endpoint: `${endpoints.GetVehicleModels.url}/${this.order.vehicle.year}/${this.order.vehicle.make}`,
|
|
payload: {}
|
|
});
|
|
},
|
|
|
|
getVehicleStyles() {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetVehicleStyles.method,
|
|
endpoint: `${endpoints.GetVehicleStyles.url}/${this.order.vehicle.year}/${this.order.vehicle.make}/${this.order.vehicle.model}`,
|
|
payload: {}
|
|
});
|
|
},
|
|
|
|
getDamageOptions(carId) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetDamageOptions.method,
|
|
endpoint: `${endpoints.GetDamageOptions.url}/${carId}`,
|
|
payload: {}
|
|
});
|
|
},
|
|
getIsVinbyAddressPermissible() {
|
|
try {
|
|
const response = globalMethods.callHttpClient({
|
|
method: endpoints.IsVinbyAddressPermissible.method,
|
|
endpoint: `${endpoints.IsVinbyAddressPermissible.url}?state=${this.order.customer.address.state}`,
|
|
payload: {}
|
|
});
|
|
return response;
|
|
} catch (responseError) {
|
|
return {
|
|
error: {
|
|
status: responseError.status
|
|
}
|
|
};
|
|
}
|
|
},
|
|
getCoveragePolicyInfo() {
|
|
const { order } = this;
|
|
const { policy } = order;
|
|
return new Promise((resolve, reject) => {
|
|
globalMethods.callHttpClient({
|
|
method: endpoints.CoveragePolicyInfo.method,
|
|
endpoint: endpoints.CoveragePolicyInfo.url,
|
|
payload: {
|
|
accountNumber: order.accountNumber?.toString(),
|
|
policyNumber: policy.policyNumber,
|
|
dateOfLoss: policy.dateOfLoss,
|
|
zipCode: policy.policyZipCode,
|
|
correlationId: order.referralCorrelationId
|
|
}
|
|
}).then((r) => {
|
|
const responsePolicy = r?.data?.policies?.[0];
|
|
policy.policyLookupSuccessful = !!responsePolicy;
|
|
if (policy.policyLookupSuccessful) {
|
|
const insured = responsePolicy.insureds?.[0];
|
|
|
|
// 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;
|
|
order.customer.firstName = insured?.firstName;
|
|
order.customer.lastName = insured?.lastName;
|
|
|
|
// populate additional fields
|
|
order.serviceLocation.zipCode = insured?.zipCode;
|
|
|
|
// populate vehicles
|
|
order.policy.vehicles = responsePolicy.vehicles ?? [];
|
|
}
|
|
return resolve(r);
|
|
}).catch((error) => {
|
|
policy.policyLookupSuccessful = false;
|
|
return reject(error);
|
|
});
|
|
});
|
|
},
|
|
registerClaim() {
|
|
const nonNumberCharRegex = /[^0-9]/g;
|
|
const { order } = this;
|
|
return new Promise((resolve, reject) => {
|
|
globalMethods.callHttpClient({
|
|
method: endpoints.RegisterClaim.method,
|
|
endpoint: endpoints.RegisterClaim.url,
|
|
payload:
|
|
{
|
|
correlationId: this.order.referralCorrelationId,
|
|
accountNumber: this.issConfig.parentAccountNumber?.toString() ?? '',
|
|
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.order.customer.phoneNumber?.replaceAll(nonNumberCharRegex, '') ?? ''
|
|
}
|
|
},
|
|
driver: {
|
|
firstName: this.order.customer.firstName,
|
|
lastName: this.order.customer.lastName
|
|
},
|
|
caller: {
|
|
homePhone: {}
|
|
},
|
|
policyInfo: {
|
|
policyNumber: this.order.policy.policyNumber,
|
|
safelitePolicy: {
|
|
policies: []
|
|
}
|
|
},
|
|
lossInfo: {
|
|
dateOfLoss: this.order.policy.dateOfLoss,
|
|
location: {
|
|
city: this.order.policy.damageCity,
|
|
state: this.order.policy.damageState,
|
|
country: 'US' // TODO set from store
|
|
},
|
|
vehicle: {
|
|
year: this.order.vehicle.year?.toString() ?? '',
|
|
make: this.order.vehicle.make,
|
|
model: this.order.vehicle.model,
|
|
vin: this.order.vehicle.vin
|
|
},
|
|
damageDescription: this.order.policy.damageCause
|
|
}
|
|
}
|
|
}).then((response) => {
|
|
const registerClaimFailed = response.data.isError;
|
|
order.payment.insuranceCoverage.isVerified = !registerClaimFailed;
|
|
order.payment.insuranceCoverage.claimNumber = null;
|
|
if (registerClaimFailed) {
|
|
this.order.payment.insuranceCoverage.coverageStatus = coverageStatuses.PENDING;
|
|
} else if (this.policy.noCoverage) {
|
|
this.order.payment.insuranceCoverage.coverageStatus = coverageStatuses.NO_COMP;
|
|
} else {
|
|
this.order.payment.insuranceCoverage.coverageStatus = coverageStatuses.VERIFIED;
|
|
this.order.payment.insuranceCoverage.claimNumber = response.data.claimNumber;
|
|
}
|
|
return resolve(response);
|
|
}, (error) => {
|
|
this.order.payment.insuranceCoverage.isVerified = false;
|
|
this.order.payment.insuranceCoverage.coverageStatus = coverageStatuses.PENDING;
|
|
this.order.payment.insuranceCoverage.claimNumber = null;
|
|
return reject(error);
|
|
});
|
|
});
|
|
},
|
|
getDuplicateReferrals() {
|
|
return new Promise((resolve, reject) => {
|
|
globalMethods.callHttpClient({
|
|
method: endpoints.DuplicateSearch.method,
|
|
endpoint: endpoints.DuplicateSearch.url(
|
|
this.issConfig.parentAccountNumber,
|
|
this.order.policy.policyNumber,
|
|
this.order.customer.phoneNumber?.replaceAll('-', '')
|
|
)
|
|
}).then((r) => {
|
|
this.applicationUser.duplicateOrders = r.data ?? [];
|
|
return resolve(r.data);
|
|
}).catch((error) => {
|
|
this.applicationUser.duplicateOrders = [];
|
|
return reject(error);
|
|
});
|
|
});
|
|
},
|
|
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
|
|
}
|
|
});
|
|
|
|
// 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
|
|
}
|
|
});
|
|
|
|
// 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}`
|
|
});
|
|
},
|
|
|
|
getPartFromCapabilityQuestionAnswer(glassLocation) {
|
|
const pageData = this.pageData(issPageValues.CAPABILITY_QUESTIONS);
|
|
|
|
const part = pageData.partsOrQuestions.find((x) => x.glassLocation === glassLocation)
|
|
.parts[0];
|
|
const { capabilityQuestionAnswers } = this.order.damage;
|
|
const capabilityQuestionAnswersForPart = capabilityQuestionAnswers.find((x) => x.glassLocation === glassLocation);
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetPartFromCapabilityAnswer.method,
|
|
endpoint: endpoints.GetPartFromCapabilityAnswer.url,
|
|
payload: {
|
|
part,
|
|
capabilityAnswerResults: capabilityQuestionAnswersForPart
|
|
}
|
|
});
|
|
},
|
|
getMobilePremiumFee() {
|
|
const damageType = this.damage.isRepair ? 'Repair' : 'Replace';
|
|
const paymentType = 'Insurance';
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetMobilePremiumFee.method,
|
|
endpoint: `${endpoints.GetMobilePremiumFee.url}/${paymentType}/${damageType}`,
|
|
logApiCall: true
|
|
});
|
|
},
|
|
getMobileTimeSlots(startDate, endDate) {
|
|
const { order } = this;
|
|
const { vehicle } = this.order;
|
|
let lineItems = [
|
|
...(order.lineItems.supportingItems ?? []),
|
|
...(order.lineItems.vaps ?? []),
|
|
...getFlattenedArrayOfLineItemsWithChildParts(order.lineItems.glassParts)
|
|
];
|
|
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,
|
|
parentAccountNumber: this.issConfig.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: order.serviceLocation.zipCode
|
|
};
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetMobileTimeSlots.method,
|
|
endpoint: endpoints.GetMobileTimeSlots.url,
|
|
payload,
|
|
logApiCall: true,
|
|
additionalSuccessEventDataHandler: (response) =>
|
|
getTimeSlotsAdditionalEventData(
|
|
response.data.provisionalTriggers,
|
|
order.serviceLocation.zipCode,
|
|
response.data.days?.[0]?.date
|
|
)
|
|
});
|
|
},
|
|
getShopTimeSlots(startDate, endDate, shopAppointmentType, providerNumber) {
|
|
const { order } = this;
|
|
const { vehicle } = this.order;
|
|
|
|
let lineItems = [
|
|
...(order.lineItems.supportingItems ?? []),
|
|
...(order.lineItems.vaps ?? []),
|
|
...getFlattenedArrayOfLineItemsWithChildParts(order.lineItems.glassParts)
|
|
];
|
|
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,
|
|
applicationName: applicationConfig.APPLICATION_NAME,
|
|
parentAccountNumber: this.issConfig.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,
|
|
additionalSuccessEventDataHandler: (response) => provisionalTriggersToString(response.data.provisionalTriggers)
|
|
});
|
|
},
|
|
async getWipers() {
|
|
const { carId } = this.order.vehicle;
|
|
// WARNING
|
|
// TODO: this is temp test code until serviceLocation is complete.
|
|
// const serviceZipCode = this.order.serviceLocation.zipCode;
|
|
const serviceZipCode = '44902';
|
|
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 [];
|
|
});
|
|
},
|
|
|
|
getProviders(serviceZipCode) {
|
|
const damageType = this.damage.isRepair ? 'Repair' : 'Replace';
|
|
const shopRadiusInMiles = 100;
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetProviders.method,
|
|
endpoint: `${endpoints.GetProviders.url}/${serviceZipCode}/${damageType}/${shopRadiusInMiles}`
|
|
});
|
|
},
|
|
|
|
async getSupportingItems() {
|
|
const glassPartsArray = this.order.lineItems.glassParts ?? [];
|
|
const { carId } = this.order.vehicle;
|
|
const { isRepair } = this.order.damage;
|
|
const { numberOfChips } = this.order.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: glassPartsArray,
|
|
numberOfRepairChips: isRepair ? numberOfChips : 0
|
|
}
|
|
});
|
|
},
|
|
|
|
async getPriceOrderItems(availableLineItems) {
|
|
let zipCodeToUse = this.order.serviceLocation.zipCode;
|
|
let ctuToUse = this.order.serviceLocation.zipCodeCtu;
|
|
const availableLineItemsFormattedForRequest = getLineItemQueryStringForPricing(availableLineItems);
|
|
const { vehicle } = this.order;
|
|
|
|
// WARNING
|
|
// TODO: this is temp test code until serviceLocation is complete.
|
|
// and ctu is available. Also, EON may need to be implemented.
|
|
zipCodeToUse = '44902';
|
|
ctuToUse = '01820';
|
|
const queryString =
|
|
`ParentAccountNumber=${applicationConfig.CASH_PARENT_ACCOUNT_NUMBER}`
|
|
+ `&CTU=${ctuToUse}`
|
|
+ `&CarId=${vehicle.carId}`
|
|
+ `&Make=${vehicle.make}`
|
|
+ `&Model=${vehicle.model}`
|
|
+ `&Year=${vehicle.year}`
|
|
+ `&EON=${this.order.eon}`
|
|
+ `&ZipCode=${zipCodeToUse}`
|
|
+ `${availableLineItemsFormattedForRequest}`;
|
|
|
|
const response = await globalMethods
|
|
.callHttpClient({
|
|
method: endpoints.GetPriceOrderItems.method,
|
|
endpoint: `${endpoints.GetPriceOrderItems.url}?${queryString}`
|
|
}).catch((error) => {
|
|
console.error(error);
|
|
return [];
|
|
});
|
|
|
|
if (response.data?.lineItems) {
|
|
const retAvailableLineItems = addPricesToLineItems(availableLineItems, response.data.lineItems);
|
|
return retAvailableLineItems;
|
|
}
|
|
return availableLineItems;
|
|
},
|
|
|
|
getMobileFeePart() {
|
|
const damageType = this.damage.isRepair ? 'Repair' : 'Replace';
|
|
const parentAccountNumber = 167132; // TODO: MAKE THIS REAL
|
|
const billToAccountNumber = 87291; // TODO: MAKE THIS REAL
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetMobileFeePart.method,
|
|
endpoint: `${endpoints.GetMobileFeePart.url}/${damageType}/${parentAccountNumber}/${billToAccountNumber}`
|
|
});
|
|
},
|
|
|
|
getServiceabilityDetails({ serviceZipCode }) {
|
|
const lineItemsWithOnlyPartNumbers = this.order.lineItems.supportingItems.map((lineItem) => ({
|
|
partNumber: lineItem.partNumber
|
|
}));
|
|
const lineItems = buildQueryStringParameterFromArrayOfComplexObjects(lineItemsWithOnlyPartNumbers, 'lineItems');
|
|
|
|
const { vehicle } = this.order;
|
|
const { carId } = vehicle;
|
|
const { damage } = this.order;
|
|
const glassArray = convertGlassPieceNamingForApi(damage.glassToReplace);
|
|
|
|
const glassPieces = buildQueryStringParameterFromArrayOfComplexObjects(glassArray, 'glassPieces');
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetServiceabilityDetails.method,
|
|
endpoint: `${endpoints.GetServiceabilityDetails.url}?zip=${serviceZipCode}&carId=${carId}&${lineItems}&${glassPieces}`
|
|
});
|
|
},
|
|
|
|
lookupVehicleByVin(vin) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LookupVehicleByVin.method,
|
|
endpoint: endpoints.LookupVehicleByVin.url,
|
|
payload: {
|
|
vin
|
|
}
|
|
});
|
|
},
|
|
|
|
setVehicle() {
|
|
return globalMethods
|
|
.callHttpClient({
|
|
method: endpoints.GetVehicle.method,
|
|
endpoint: `${endpoints.GetVehicle.url}/${this.order.vehicle.year}/${this.order.vehicle.make}/${this.order.vehicle.model}/${this.order.vehicle.style}`,
|
|
payload: {}
|
|
})
|
|
.then((response) => {
|
|
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.workOrderNumber = response.workOrderNumber;
|
|
this.applicationUser.savedSessionId = response.savedSessionId;
|
|
this.applicationUser.crmCustomerId = response.crmCustomerId.toString();
|
|
},
|
|
|
|
saveSession() {
|
|
const { vehicle, damage, policy, customer, contactInfo, payment,
|
|
lineItems, serviceLocation, schedule } = this.order;
|
|
const newGlassToReplace = convertGlassPieceNamingForApi(damage.glassToReplace);
|
|
return new Promise((resolve, reject) => {
|
|
globalMethods.callHttpClient({
|
|
method: endpoints.SaveSession.method,
|
|
endpoint: endpoints.SaveSession.url,
|
|
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
|
|
},
|
|
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: customer.phoneNumber,
|
|
policyEmail: customer.emailAddress,
|
|
policyState: customer.address.state
|
|
},
|
|
policyNumber: policy.policyNumber,
|
|
policyZipCode: policy.policyZipCode,
|
|
noCoverage: policy.noCoverage,
|
|
policyLookupSuccessful: policy.policyLookupSuccessful,
|
|
originalDeductible: this.order.originalDeductible,
|
|
currentDeductible: this.order.currentDeductible
|
|
},
|
|
customer: {
|
|
address: {
|
|
streetAddress: customer.address?.streetAddress,
|
|
streetAddress2: customer.address?.streetAddress2,
|
|
city: customer.address?.city,
|
|
state: customer.address?.state,
|
|
zipCode: customer.address?.zipCode
|
|
},
|
|
emailAddress: contactInfo.emailAddress,
|
|
firstName: contactInfo.firstName || customer.firstName,
|
|
lastName: contactInfo.lastName || customer.lastName,
|
|
phoneNumber: contactInfo.phoneNumber,
|
|
optInSms: contactInfo.requestTextUpdates ?? false
|
|
},
|
|
lineItems: {
|
|
glassParts: lineItems.glassParts,
|
|
supportingItems: lineItems.supportingItems,
|
|
vaps: lineItems.vaps
|
|
},
|
|
payment: {
|
|
InsuranceCoverage: {
|
|
isVerified: payment.insuranceCoverage?.isVerified ?? false,
|
|
coverageStatus: payment.insuranceCoverage?.coverageStatus,
|
|
claimNumber: payment.insuranceCoverage?.claimNumber
|
|
},
|
|
parentAccountNumber: this.issConfig.parentAccountNumber
|
|
},
|
|
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: {
|
|
providerNumber: serviceLocation.provider?.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
|
|
},
|
|
additionalSuccessEventDataHandler: (response) =>
|
|
`Email provided: ${customer.emailAddress ? 'true' : 'false'}`
|
|
}).then((response) => resolve(response), (error) => reject(error));
|
|
});
|
|
},
|
|
|
|
loadSession() {
|
|
const { applicationUser, order, issConfig } = this;
|
|
// TODO how to get savedSessionId for a duplicate referral?
|
|
return new Promise((resolve, reject) => {
|
|
globalMethods.callHttpClient({
|
|
method: endpoints.LoadSession.method,
|
|
endpoint: endpoints.LoadSession.url,
|
|
payload: {
|
|
savedSessionId: applicationUser.savedSessionId?.toString(),
|
|
referralNumber: order.referralNumber?.toString(),
|
|
referralDate: order.referralDate?.toString(),
|
|
parentAccountNumber: issConfig.parentAccountNumber,
|
|
referralCorrelationId: order.referralCorrelationId
|
|
}
|
|
}).then((response) => {
|
|
const { data } = response;
|
|
if (!data) {
|
|
// TODO how should we handle this case?
|
|
return resolve(data);
|
|
}
|
|
applicationUser.crmCustomerId = data.applicationUser?.crmCustomerId;
|
|
applicationUser.experiments = data.applicationUser?.experiments ?? [];
|
|
applicationUser.lastPageVisited = data.applicationUser?.lastPage;
|
|
applicationUser.pageData = data.applicationUser?.pageData ?? {};
|
|
applicationUser.savedSessionId = data.applicationUser?.savedSessionId; // TODO this might just be what is passed
|
|
applicationUser.hasSentSaveQuoteEmail = data.applicationUser?.hasSentSaveQuoteEmail;
|
|
|
|
order.vehicle.registration.licensePlate = data.order?.vehicle?.registration?.licensePlateNumber;
|
|
order.vehicle.imageUrl = data.order?.vehicle?.imageUrl;
|
|
order.vehicle.imageColor = data.order?.vehicle?.imageVifColor;
|
|
order.vehicle.imageVifNumber = data.order?.vehicle?.imageVifNumber;
|
|
order.vehicle.year = data.order?.vehicle?.year;
|
|
order.vehicle.make = data.order?.vehicle?.make;
|
|
order.vehicle.model = data.order?.vehicle?.model;
|
|
order.vehicle.style = data.order?.vehicle?.style;
|
|
order.vehicle.carId = data.order?.vehicle?.carId;
|
|
order.vehicle.category = data.order?.vehicle?.category;
|
|
order.vehicle.vin = data.order?.vehicle?.vin;
|
|
|
|
order.customer.emailAddress = data.order?.customer?.emailAddress;
|
|
order.customer.firstName = data.order?.policy?.policyHolder?.policyFirstName;
|
|
order.customer.lastName = data.order?.policy?.policyHolder?.policyLastName;
|
|
order.customer.phoneNumber = data.order?.policy?.policyHolder?.policyPhoneNumber;
|
|
|
|
order.customer.address.streetAddress = data.order?.customer?.address?.streetAddress;
|
|
order.customer.address.streetAddress2 = data.order?.customer?.address?.streetAddress2;
|
|
order.customer.address.city = data.order?.customer?.address?.city;
|
|
order.customer.address.state = data.order?.customer?.address?.state;
|
|
order.customer.address.zipCode = data.order?.customer?.address?.zipCode;
|
|
|
|
order.damage.isRepair = data.order?.damage?.isRepair;
|
|
order.damage.numberOfChips = data.order?.damage?.numberOfChips;
|
|
order.damage.glassToReplace = data.order?.damage?.glassToReplace;
|
|
order.damage.capabilityQuestionAnswers = data.order?.damage?.capabilityQuestionAnswers;
|
|
order.damage.moldingQuestionAnswers = data.order?.damage?.moldingQuestionAnswers;
|
|
order.damage.partQuestionAnswers = data.order?.damage?.partQuestionAnswers;
|
|
|
|
order.policy.policyNumber = data.order?.policy?.policyNumber;
|
|
order.policy.policyZipCode = data.order?.policy?.policyZipCode;
|
|
order.policy.noCoverage = data.order?.policy?.noCoverage;
|
|
order.policy.policyLookupSuccessful = data.order?.policy?.policyLookupSuccessful; // TODO probably don't need to load this
|
|
order.policy.dateOfLoss = data.order?.damage?.dateOfLoss;
|
|
order.policy.damageCause = data.order?.damage?.damageCause;
|
|
order.policy.damageState = data.order?.damage?.damageState;
|
|
order.policy.damageCity = data.order?.damage?.damageCity;
|
|
order.policy.isDamageGlassOnly = data.order?.damage?.isDamageGlassOnly;
|
|
|
|
order.originalDeductible = data.order?.policy?.originalDeductible;
|
|
order.currentDeductible = data.order?.policy?.currentDeductible;
|
|
|
|
order.lineItems.glassParts = data.order?.lineItems?.glassParts;
|
|
// TODO otherParts
|
|
order.lineItems.supportingItems = data.order?.lineItems?.supportingItems;
|
|
order.lineItems.vaps = data.order?.lineItems?.vaps;
|
|
|
|
order.payment.insuranceCoverage.isVerified = data.order?.payment?.insuranceCoverage?.isVerified;
|
|
order.payment.insuranceCoverage.coverageStatus = data.order?.payment?.insuranceCoverage?.coverageStatus;
|
|
const parentAccountNumber = Number.isNaN(data.order?.payment?.parentAccountNumber)
|
|
? 0
|
|
: data.order?.payment?.parentAccountNumber;
|
|
order.payment.parentAccountNumber = parentAccountNumber;
|
|
issConfig.parentAccountNumber = parentAccountNumber;
|
|
order.payment.insuranceCoverage.claimNumber = data.order?.payment?.insuranceCoverage?.claimNumber;
|
|
|
|
order.serviceLocation.address = data.order?.serviceLocation?.streetAddress;
|
|
order.serviceLocation.address2 = data.order?.serviceLocation?.streetAddress2;
|
|
order.serviceLocation.city = data.order?.serviceLocation?.city;
|
|
order.serviceLocation.state = data.order?.serviceLocation?.state;
|
|
order.serviceLocation.zipCode = data.order?.serviceLocation?.zipCode;
|
|
order.serviceLocation.zipCodeCtu = data.order?.serviceLocation?.zipCodeCtu;
|
|
order.serviceLocation.appointmentType = data.order?.serviceLocation?.appointmentType;
|
|
order.serviceLocation.isVehicleProtected = data.order?.serviceLocation?.isVehicleProtected;
|
|
order.serviceLocation.provider.providerNumber = data.order?.serviceLocation?.provider?.providerNumber;
|
|
order.serviceLocation.provider.address.streetAddress = data.order?.serviceLocation?.provider?.address?.streetAddress;
|
|
order.serviceLocation.provider.address.city = data.order?.serviceLocation?.provider?.address?.city;
|
|
order.serviceLocation.provider.address.state = data.order?.serviceLocation?.provider?.address?.state;
|
|
order.serviceLocation.provider.address.zipCode = data.order?.serviceLocation?.provider?.address?.zipCode;
|
|
order.serviceLocation.provider.address.zipCodeCtu = data.order?.serviceLocation?.provider?.address?.zipCodeCtu;
|
|
|
|
order.contactInfo.firstName = data.order?.customer?.firstName;
|
|
order.contactInfo.lastName = data.order?.customer?.lastName;
|
|
order.contactInfo.emailAddress = data.order?.customer?.emailAddress;
|
|
order.contactInfo.phoneNumber = data.order?.customer?.phoneNumber;
|
|
order.contactInfo.requestTextUpdates = data.order?.customer?.isSmsOptIn; // TODO confirm
|
|
order.contactInfo.notesForTechnician = data.order?.serviceLocation?.techNotes;
|
|
// TODO service phone number ??
|
|
// TODO isSmsOptIn service ??
|
|
|
|
order.schedule.date = data.order?.schedule?.date;
|
|
order.schedule.startTime = data.order?.schedule?.startTime;
|
|
order.schedule.endTime = data.order?.schedule?.endTime;
|
|
order.schedule.routeCode = data.order?.schedule?.routeCode;
|
|
order.schedule.jobMaxMinutes = data.order?.schedule?.jobMaxMinutes;
|
|
order.schedule.jobMinMinutes = data.order?.schedule?.jobMinMinutes;
|
|
|
|
order.referralNumber = data.order?.referralNumber;
|
|
order.referralDate = data.order?.referralDate;
|
|
order.referralCorrelationId = data.order?.referralCorrelationId;
|
|
order.referralSequenceNumber = data.order?.referralSequenceNumber;
|
|
order.eon = data.order?.eon;
|
|
// TODO order.workOrderNumber not set, but this likely is not an issue since WON => will not return
|
|
return resolve(data);
|
|
}, (error) => {
|
|
reject(error);
|
|
});
|
|
});
|
|
},
|
|
|
|
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.address2 = serviceLocationInfo.address2;
|
|
this.order.serviceLocation.city = serviceLocationInfo.city;
|
|
this.order.serviceLocation.state = serviceLocationInfo.state;
|
|
this.order.serviceLocation.zipCode = serviceLocationInfo.zipCode;
|
|
this.order.serviceLocation.zipCodeCtu = serviceLocationInfo.zipCodeCtu;
|
|
this.order.serviceLocation.appointmentType = serviceLocationInfo.appointmentType;
|
|
this.order.serviceLocation.isVehicleProtected = serviceLocationInfo.isVehicleProtected;
|
|
|
|
this.order.serviceLocation.provider = {
|
|
providerNumber: serviceLocationInfo.provider?.providerNumber,
|
|
address: {
|
|
streetAddress: serviceLocationInfo.provider?.address?.streetAddress,
|
|
city: serviceLocationInfo.provider?.address?.city,
|
|
state: serviceLocationInfo.provider?.address?.state,
|
|
zipCode: serviceLocationInfo.provider?.address?.zipCode,
|
|
zipCodeCtu: serviceLocationInfo.provider?.address?.zipCodeCtu
|
|
}
|
|
};
|
|
},
|
|
|
|
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(context) {
|
|
console.log('Reset service location and dependencies...');
|
|
this.resetServiceLocationAppointmentType();
|
|
this.resetServiceLocationProvider();
|
|
this.resetSchedule();
|
|
},
|
|
resetServiceLocationAppointmentType() {
|
|
console.log('Reset service location appointment type...');
|
|
this.order.serviceLocation.appointmentType = null;
|
|
},
|
|
resetServiceLocationProvider() {
|
|
console.log('Reset service location provider...');
|
|
this.order.serviceLocation.provider = {
|
|
providerNumber: null,
|
|
address: {
|
|
streetAddress: null,
|
|
city: null,
|
|
state: null,
|
|
zipCode: null,
|
|
zipCodeCtu: null
|
|
}
|
|
};
|
|
},
|
|
resetServiceLocationMobileAddress() {
|
|
console.log('Reset service location mobile address...');
|
|
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;
|
|
},
|
|
|
|
updateSupportingItems(partsData) {
|
|
this.order.lineItems.supportingItems = partsData;
|
|
},
|
|
|
|
updateVaps(partsData) {
|
|
this.order.lineItems.vaps = partsData;
|
|
},
|
|
|
|
updateVehicle(vehicle) {
|
|
// Assuming that the method caller pass all the properties.
|
|
// otherwise need to check for undefined for every property.
|
|
this.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.vin = vehicle.vin;
|
|
this.order.vehicle.imageUrl = vehicle.imageUrl;
|
|
this.order.vehicle.imageVifNumber = vehicle.imageVifNumber;
|
|
this.order.vehicle.imageColor = vehicle.imageVifColor;
|
|
|
|
// These could be undefined
|
|
this.order.policy.noCoverage = vehicle.noCoverage;
|
|
this.order.payment.insuranceCoverage.coverageStatus = vehicle.noCoverage
|
|
? coverageStatuses.NO_COMP
|
|
: coverageStatuses.PENDING;
|
|
this.order.policy.deductible.replace = vehicle.deductible;
|
|
this.order.policy.deductible.repair = vehicle?.repairWaived ?? false ? 0 : vehicle.deductible;
|
|
this.order.policy.endorsements = vehicle?.endorsements;
|
|
|
|
// TODO logic should be more complicated later on
|
|
this.order.originalDeductible = parseFloat(vehicle.deductible);
|
|
this.order.currentDeductible = parseFloat(vehicle.deductible);
|
|
|
|
this.resetSupportingItemsState();
|
|
this.resetVapsState();
|
|
},
|
|
|
|
updateVehicleVin(vin) {
|
|
this.order.vehicle.vin = vin;
|
|
},
|
|
|
|
resetVehicleState() {
|
|
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;
|
|
},
|
|
|
|
resetGlassPartsState() {
|
|
this.order.lineItems.glassParts = 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() {
|
|
console.log('Reset Schedule...');
|
|
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;
|
|
|
|
// premium appointment fee used on schedule page also needs reset when schedule is reset
|
|
const { supportingItems } = this.order.lineItems;
|
|
const premiumAppointmentFeeIndex = supportingItems?.findIndex((item) => item.partType === PREMIUM_FEE_PART_TYPE);
|
|
|
|
if (premiumAppointmentFeeIndex >= 0) {
|
|
supportingItems.splice(premiumAppointmentFeeIndex, 1);
|
|
state.order.lineItems.supportingItems = supportingItems;
|
|
}
|
|
},
|
|
resetSupportingItemsState() {
|
|
this.order.lineItems.supportingItems = null;
|
|
},
|
|
resetVapsState() {
|
|
this.order.lineItems.vaps = 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.clientDisplayName = 'Generic Insurance';
|
|
this.issConfig.parentAccountNumber = 0;
|
|
this.issConfig.styleSheet = '';
|
|
this.issConfig.isCoverageEnabled = false;
|
|
this.issConfig.isAuthenticated = 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;
|
|
},
|
|
|
|
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.customer.phoneNumber = welcomePageModel?.phoneNumber;
|
|
this.order.customer.emailAddress = welcomePageModel?.email;
|
|
},
|
|
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.serviceLocation.zipCode = customerQuestions.addressQuestions.zipCode;
|
|
},
|
|
updatePolicyITACFlag(isITAC) {
|
|
this.order.policy.isITAC = isITAC;
|
|
},
|
|
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.resetSupportingItemsState();
|
|
this.resetVapsState();
|
|
|
|
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);
|
|
},
|
|
saveGlassParts(glassParts) {
|
|
if (!deepEqual(glassParts, this.order.lineItems.glassParts)) {
|
|
this.resetServiceLocationAndDependencies();
|
|
}
|
|
this.order.lineItems.glassParts = glassParts;
|
|
},
|
|
saveSupportingItems(supportingItems) {
|
|
if (!deepEqual(supportingItems, this.order.lineItems.supportingItems)) {
|
|
this.resetServiceLocationAndDependencies();
|
|
}
|
|
|
|
this.order.lineItems.supportingItems = supportingItems;
|
|
},
|
|
saveSupportingItemsSuppressingStateResetting(supportingItems) {
|
|
this.order.lineItems.supportingItems = supportingItems;
|
|
},
|
|
saveVaps(vaps) {
|
|
this.order.lineItems.vaps = vaps;
|
|
},
|
|
|
|
// Price order actions
|
|
async priceOrderItemsAndSaveServerData(availableLineItems, serviceZipCode, serviceZipCodeCtu) {
|
|
const zipCodeToUse = serviceZipCode || this.order.serviceLocation.zipCode;
|
|
const ctuToUse = serviceZipCodeCtu || this.order.serviceLocation.zipCodeCtu;
|
|
const flattenedLineItemsWithChildParts = getFlattenedArrayOfLineItemsWithChildParts(availableLineItems);
|
|
const lineItemsWithOnlyPartNumbers = flattenedLineItemsWithChildParts.map((lineItem) => ({
|
|
partNumber: lineItem.partNumber
|
|
}));
|
|
const availableLineItemsFormattedForRequest =
|
|
buildQueryStringParameterFromArrayOfComplexObjects(
|
|
lineItemsWithOnlyPartNumbers,
|
|
'lineItems'
|
|
);
|
|
|
|
const { vehicle } = this.order;
|
|
|
|
let queryString =
|
|
`ParentAccountNumber=${applicationConfig.CASH_PARENT_ACCOUNT_NUMBER}`
|
|
+ `&CTU=${ctuToUse}`
|
|
+ `&CarId=${vehicle.carId}`
|
|
+ `&Make=${vehicle.make}`
|
|
+ `&Model=${vehicle.model}`
|
|
+ `&Year=${vehicle.year}`
|
|
+ `&EON=${this.order.eon}`
|
|
+ `&ZipCode=${zipCodeToUse}`
|
|
+ `&${availableLineItemsFormattedForRequest}`;
|
|
|
|
const lineItemServerData = this.order.lineItems.serverData;
|
|
if (lineItemServerData) {
|
|
queryString += `&ServerData=${encodeURIComponent(lineItemServerData)}`;
|
|
}
|
|
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.GetPriceOrderItems.method,
|
|
endpoint: `${endpoints.GetPriceOrderItems.url}?${queryString}`
|
|
});
|
|
|
|
// context.commit(storeMutations.UPDATE_LINE_ITEMS_SERVER_DATA, response.data.serverData);
|
|
return addPricesToLineItems(availableLineItems, response.data.lineItems);
|
|
},
|
|
saveProviderPreferenceData(data) {
|
|
this.updatePageData({ page: issPageValues.PROVIDER_PREFERENCE, data });
|
|
},
|
|
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() {
|
|
if (!localStorage.getItem(storeId)) {
|
|
this.$state = state;
|
|
}
|
|
},
|
|
|
|
// Location API Actions
|
|
getAlertReasonsByCtu(ctu) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetAlertReasons.method,
|
|
endpoint: `${endpoints.GetAlertReasons.url}/${ctu}`,
|
|
payload: {},
|
|
logApiCall: true
|
|
});
|
|
},
|
|
|
|
// 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({ userId, sessionKey, pageName, experiment }) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LogExperimentExposureIfAssigned.method,
|
|
endpoint: endpoints.LogExperimentExposureIfAssigned.url,
|
|
payload: {
|
|
experimentForLogging: {
|
|
userId,
|
|
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,
|
|
pageName
|
|
}
|
|
}
|
|
});
|
|
},
|
|
logPageView({ userId, sessionKey, pageName, sessionId, action, event, shouldUseSessionId, experimentsForUser }) {
|
|
const payload = {
|
|
userId,
|
|
sessionKey,
|
|
sessionId,
|
|
pageName,
|
|
applicationName: applicationConfig.APPLICATION_NAME,
|
|
action,
|
|
event,
|
|
shouldUseSessionId,
|
|
experimentsForUser
|
|
};
|
|
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.LogPageView.method,
|
|
endpoint: endpoints.LogPageView.url,
|
|
payload,
|
|
logApiCall: false
|
|
}).then(
|
|
(response) => response,
|
|
(error) => {
|
|
console.log(`Analytics Service Error: ${error.data}`);
|
|
}
|
|
);
|
|
},
|
|
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
|
|
}).then(
|
|
(response) => response,
|
|
(error) => {
|
|
console.log(`Analytics Service Error: ${error.data}`);
|
|
}
|
|
);
|
|
},
|
|
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
|
|
}).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;
|
|
},
|
|
|
|
updateContactInfo(contactInfo) {
|
|
this.order.contactInfo.firstName = contactInfo?.firstName ?? '';
|
|
this.order.contactInfo.lastName = contactInfo?.lastName ?? '';
|
|
this.order.contactInfo.emailAddress = contactInfo?.emailAddress ?? '';
|
|
this.order.contactInfo.phoneNumber = contactInfo?.phoneNumber ?? '';
|
|
this.order.contactInfo.requestTextUpdates = contactInfo?.requestTextUpdates ?? false;
|
|
this.order.contactInfo.notesForTechnician = contactInfo?.notesForTechnician ?? '';
|
|
},
|
|
|
|
GetExperimentsByUser(userId) {
|
|
return globalMethods.callHttpClient({
|
|
method: endpoints.GetExperimentsByUser.method,
|
|
endpoint: `${endpoints.GetExperimentsByUser.url}/${userId}`,
|
|
payload: {}
|
|
});
|
|
},
|
|
|
|
async runExperimentsForTrigger({ userId, triggerEvent, triggerValue }) {
|
|
if (triggerEvent === experimentTriggers.SITE_ENTRY) {
|
|
this.updateTriggeredSiteEntry(true);
|
|
}
|
|
|
|
const payload = {
|
|
applicationName: applicationConfig.APPLICATION_NAME,
|
|
userId,
|
|
triggerEvent,
|
|
triggerValue,
|
|
experimentOrder: this.experimentOrder
|
|
};
|
|
|
|
const response = await globalMethods.callHttpClient({
|
|
method: endpoints.RunExperimentsForTrigger.method,
|
|
endpoint: endpoints.RunExperimentsForTrigger.url,
|
|
payload
|
|
});
|
|
|
|
this.updateExperiments(response.data.experiments);
|
|
},
|
|
|
|
async validateZip({ zip }) {
|
|
return await globalMethods.callHttpClient({
|
|
method: endpoints.ValidateZip.method,
|
|
endpoint: `${endpoints.ValidateZip.url}/${zip}`
|
|
});
|
|
},
|
|
|
|
async validateClientTag(clientTag) {
|
|
return await 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
|
|
});
|
|
},
|
|
|
|
saveServiceLocation(serviceLocationInfo) {
|
|
if (this.order.serviceLocation) {
|
|
if (
|
|
serviceLocationInfo.zipCode !== this.order.serviceLocation.zipCode
|
|
|| !providersEqual(
|
|
serviceLocationInfo.provider,
|
|
this.order.serviceLocation.provider
|
|
)
|
|
|| serviceLocationInfo.appointmentType
|
|
!== this.order.serviceLocation.appointmentType
|
|
) {
|
|
this.resetSchedule();
|
|
}
|
|
}
|
|
this.updateServiceLocation(serviceLocationInfo);
|
|
},
|
|
|
|
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);
|
|
},
|
|
|
|
resetRegistrationAndDependencies() {
|
|
this.resetRegistrationState();
|
|
this.resetGlassPartsState();
|
|
this.resetSupportingItemsState();
|
|
this.resetVapsState();
|
|
},
|
|
|
|
resetDamageAndDependencies() {
|
|
this.resetDamageState();
|
|
this.resetGlassPartsState();
|
|
this.resetSupportingItemsState();
|
|
this.resetVapsState();
|
|
},
|
|
|
|
resetPartsAndDependencies() {
|
|
this.resetGlassPartsState();
|
|
this.resetSupportingItemsState();
|
|
this.resetVapsState();
|
|
|
|
this.resetServiceLocationAndDependencies();
|
|
},
|
|
|
|
resetPageFields() {
|
|
this.order.policy.policyNumber = null;
|
|
this.order.policy.dateOfLoss = null;
|
|
this.order.policy.damageCause = null;
|
|
this.order.policy.damageCity = null;
|
|
this.order.policy.damageState = null;
|
|
this.order.policy.isITAC = null;
|
|
this.order.customer.phoneNumber = null;
|
|
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;
|
|
this.resetVehicleState();
|
|
this.resetDamageState();
|
|
}
|
|
|
|
},
|
|
persist: true
|
|
});
|
|
|
|
// Private Functions
|
|
|
|
function getHasRecalibrationPart(state) {
|
|
const hasRequiresRecalibration = getNonFalseValuesOfPropertyInArrayOfObjects(state.order.lineItems.glassParts, 'requiresRecalibration')?.length > 0;
|
|
const hasRecalibrationType = getNonFalseValuesOfPropertyInArrayOfObjects(state.order.lineItems.glassParts, 'recalibrationType')?.length > 0;
|
|
|
|
if (hasRequiresRecalibration) {
|
|
if (hasRecalibrationType) {
|
|
// Has both 'requiresRecalibration' and 'recalibrationType' and 'recalibrationType'
|
|
return (
|
|
getNonFalseValuesOfPropertyInArrayOfObjects(
|
|
state.order.lineItems.glassParts,
|
|
'recalibrationType'
|
|
)[0].toLowerCase() !== 'unknown'
|
|
);
|
|
}
|
|
// Has 'requiresRecalibration' but no 'recalibrationType' at all
|
|
return true;
|
|
}
|
|
// Does not have 'requiresRecalibration'
|
|
return false;
|
|
}
|
|
|
|
function getNonFalseValuesOfPropertyInArrayOfObjects(array, propertyName) {
|
|
return (array ?? []).map((x) => x[propertyName]).filter((x) => x);
|
|
}
|
|
|
|
function sortArrayOfObjectsByPropertyValue(arrayOfObjects, propertyName) {
|
|
if (!arrayOfObjects) return null;
|
|
|
|
return arrayOfObjects.sort((a, b) => {
|
|
if (a[propertyName] < b[propertyName]) return -1;
|
|
if (a[propertyName] > b[propertyName]) return 1;
|
|
return 0;
|
|
});
|
|
}
|
|
|
|
function convertGlassPieceNamingForApi(glassArray) {
|
|
if (!glassArray || glassArray.length === 0) return [];
|
|
|
|
// check if array already converted. (likely when a session has been saved previously and then reloaded)
|
|
if (glassArray[0].location !== undefined) {
|
|
return glassArray;
|
|
}
|
|
|
|
const converted = [];
|
|
glassArray.forEach((glass) => {
|
|
converted.push({
|
|
location: glass.glassLocation,
|
|
name: glass.glassName
|
|
});
|
|
});
|
|
return converted;
|
|
}
|
|
|
|
function convertResultsForApi(resultsArray) {
|
|
if (!resultsArray) return [];
|
|
const converted = [];
|
|
resultsArray.forEach((answer) => {
|
|
converted.push({
|
|
location: answer.glassLocation,
|
|
name: answer.glassName,
|
|
result: answer.result
|
|
});
|
|
});
|
|
return converted;
|
|
}
|
|
|
|
function convertGlassPieceNamingFromApi(glassArray) {
|
|
glassArray.forEach((glass) => {
|
|
glass.glassLocation = glass.glassPiece.location;
|
|
glass.glassName = glass.glassPiece.name;
|
|
delete glass.glassPiece;
|
|
return glass;
|
|
});
|
|
return glassArray;
|
|
}
|
|
|
|
function addPricesToLineItems(lineItems, pricingLineItems) {
|
|
lineItems.forEach((lineItem) => {
|
|
if (lineItem.childParts) {
|
|
addPricesToLineItems(lineItem.childParts, pricingLineItems);
|
|
}
|
|
|
|
const lineItemIndex = pricingLineItems.findIndex((pricingLineItem) => pricingLineItem.partNumber === lineItem.partNumber);
|
|
|
|
if (lineItemIndex > -1) {
|
|
const pricedLineItem = pricingLineItems[lineItemIndex];
|
|
lineItem.laborAmount = pricedLineItem.laborAmount;
|
|
lineItem.sellingPrice = pricedLineItem.sellingPrice;
|
|
lineItem.kitPrice = pricedLineItem.kitPrice;
|
|
}
|
|
});
|
|
return lineItems;
|
|
}
|
|
|
|
function getLineItemQueryStringForPricing(lineItems) {
|
|
return lineItems.map((lineItem, index) => {
|
|
let queryStringSnippet = `&LineItems[${index}].partNumber=${lineItem.partNumber}`;
|
|
if (lineItem.childParts) {
|
|
queryStringSnippet += getLineItemQueryStringForPricing(lineItem.childParts);
|
|
}
|
|
|
|
return queryStringSnippet;
|
|
}).join('');
|
|
}
|
|
|
|
function getFlattenedArrayOfLineItemsWithChildParts(lineItems) {
|
|
let flattenedArray = [];
|
|
lineItems?.forEach((lineItem) => {
|
|
flattenedArray.push(lineItem);
|
|
if (lineItem.childParts) {
|
|
flattenedArray = [
|
|
...flattenedArray,
|
|
...getFlattenedArrayOfLineItemsWithChildParts(lineItem.childParts)
|
|
];
|
|
}
|
|
});
|
|
return flattenedArray;
|
|
}
|
|
|
|
function buildQueryStringParameterFromArrayOfComplexObjects(arrayOfObjects, parameterName) {
|
|
let queryStringParameter = '';
|
|
for (let i = 0; i < arrayOfObjects.length; i++) {
|
|
for (const [key, value] of Object.entries(arrayOfObjects[i])) {
|
|
queryStringParameter += `${parameterName}[${i}].${key}=${value}&`;
|
|
}
|
|
}
|
|
// Remove trailing &
|
|
return queryStringParameter.slice(0, -1);
|
|
}
|
|
|
|
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(',')}`;
|
|
}
|