DigitalConsumer.ISS/src/store/index.js

1367 lines
48 KiB
JavaScript

import { defineStore } from 'pinia';
import { endpoints } from '@/constants/endpoints.js';
import { getDateForSavedSessionTimeout } from '@/helpers/session-helper';
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';
const storeId = 'main';
const getDefaultState = () => {
return {
order: {
vehicle: {
year: null,
make: null,
model: null,
style: null,
carId: null,
category: null,
vin: null,
imageUrl: null,
imageVifNumber: null,
imageColor: null,
registration: {
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
},
customer: {
address: {
streetAddress: null,
streetAddress2: null,
city: null,
state: null,
zipCode: null
},
firstName: null,
lastName: null,
emailAddress: null,
phoneNumber: null
},
serviceLocation: {
address: null,
city: null,
state: null,
zipCode: null,
zipCodeCtu: null
},
lineItems: {
glassParts: null,
otherParts: null,
supportingItems: null,
vaps: null
},
payment: {
isInsurance: true,
insuranceCoverage: {
isVerified: false
}
},
referralNumber: null,
referralDate: null,
},
applicationUser: {
experiments: [],
eventBus: [],
pageData: {},
savedSessionTimeout: getDateForSavedSessionTimeout(),
saveSessionPromise: null,
savedSessionId: null,
crmCustomerId: null,
lastPageVisited: null,
triggeredSiteEntry: false
},
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: '',
accountNumber: 0,
isCoverageEnabled: false, // Indicates if we should be calling coverage on this flow.
isAuthenticated: false, // Indicates if user is authenticated or not.
enableTPAFlow: false, // Indicates if the TPA flow is supported for this client.
returnURL: null,
returnURL2: null,
disabledFields: {
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,
hasAnyNonWindshieldGlassParts: (state) => !state.order.policy.isDamageGlassOnly,
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) => {
return state.applicationUser.pageData[page];
},
customerData: (state) => {
if (state.order.vehicle.registration.address)
{
const registration = state.order.vehicle.registration;
return {
addressQuestions: {
streetAddress: registration.address,
city: registration.city,
state: registration.state,
zipCode: registration.zipCode
},
firstName: registration.firstName,
lastName: registration.lastName
}
}
else {
const address = state.order.customer.address;
return {
addressQuestions: {
streetAddress: address.streetAddress,
city: address.city,
state: address.state,
zipCode: address.zipCode
},
firstName: state.order.customer.firstName,
lastName: state.order.customer.lastName
}
}
},
experimentOrder: (state) => {
return {
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) => {
return 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: licenseLastName,
licenseStreetAddress: licenseStreetAddress,
licenseZip: licenseZip,
licenseState: licenseState
}
});
},
getRouteInfo(pageName) {
return globalMethods.callHttpClient({
method: endpoints.GetRouteInfo.method,
endpoint: endpoints.GetRouteInfo.url(applicationConfig.APPLICATION_ABBREVIATION),
payload: {
pageName: 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({
methods: 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({accountNumber,policyNumber,dateOfLoss}){
try{
const response = globalMethods.callHttpClient({
method:endpoints.CoveragePolicyInfo.method,
endpoint:endpoints.CoveragePolicyInfo.url,
payload: {
accountNumber: accountNumber,
policyNumber: policyNumber,
dateOfLoss: dateOfLoss
}
});
return response;
} catch (responseError) {
return {
error: {
status: responseError.status
}
};
}
},
async lookupVinByPlate(licensePlate, licenseState) {
try {
const response = await globalMethods.callHttpClient({
method: endpoints.LookupVinByPlate.method,
endpoint: endpoints.LookupVinByPlate.url,
payload: {
licensePlate: licensePlate,
licenseState: licenseState
}
});
return response;
} catch (responseError) {
return {
error: {
status: responseError.status
}
};
}
},
// PartsOrQuestions API Actions
async getPartsOrQuestions() {
this.resetPartsAndDependencies();
const vehicle = this.vehicle;
const damage = this.damage;
const order = this.order;
const carId = vehicle.carId;
const glassArray = damage.glassToReplace;
const zipCode = vehicle.registration.zipCode ? vehicle.registration.zipCode : order.customer.address.zipCode;
const vin = vehicle.vin;
// 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: carId,
glassPieces: glassArrayForPayload,
zip: zipCode,
vin: vin
}
});
// Flatten location and name properties
response.data.partsOrQuestions = convertGlassPieceNamingFromApi(
response.data.partsOrQuestions
);
return response;
},
async getParts() {
const vehicle = this.order.vehicle;
const damage = this.order.damage;
const order = this.order;
const carId = vehicle.carId;
const glassArray = damage.glassToReplace;
const resultsArray = damage.partQuestionAnswers;
const zipCode = vehicle.registration.zipCode ? vehicle.registration.zipCode : order.customer.address.zipCode;
const vin = vehicle.vin;
// create a new array to avoid mutating state
const glassArrayForPayload = convertGlassPieceNamingForApi(glassArray);
const resultsArrayForPayload = convertResultsForApi(resultsArray);
const response = await globalMethods.callHttpClient({
method: endpoints.GetParts.method,
endpoint: endpoints.GetParts.url,
payload: {
carId: carId,
glassPieces: glassArrayForPayload,
answerResults: resultsArrayForPayload,
zip: zipCode,
vin: vin
}
});
// 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.capabilityQuestionAnswers;
const capabilityQuestionAnswersForPart = capabilityQuestionAnswers.find(
(x) => x.glassLocation === glassLocation
);
return globalMethods.callHttpClient({
method: endpoints.GetPartFromCapabilityAnswer.method,
endpoint: endpoints.GetPartFromCapabilityAnswer.url,
payload: {
part,
capabilityAnswerResults: capabilityQuestionAnswersForPart
}
});
},
async getWipers() {
const carId = this.order.vehicle.carId;
//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 [];
});
},
async getSupportingItems() {
const glassPartsArray = this.order.lineItems.glassParts ?? [];
const carId = this.order.vehicle.carId;
const isRepair = this.order.damage.isRepair;
const numberOfChips = this.order.damage.numberOfChips;
return globalMethods
.callHttpClient({
method: endpoints.GetSupportingItems.method,
endpoint: endpoints.GetSupportingItems.url,
payload: {
carId: carId,
damageType: isRepair ? 'Repair' : 'Replace',
parentAccountNumber: applicationConfig.CASH_PARENT_ACCOUNT_NUMBER,
parts: glassPartsArray,
numberOfRepairChips: isRepair ? numberOfChips : 0
}
});
},
async getPriceOrderItems(availableLineItems) {
let zipCodeToUse = this.order.serviceLocation.zipCode;
let ctuToUse = this.order.serviceLocation.zipCodeCtu;
const availableLineItemsFormattedForRequest =
getLineItemQueryStringForPricing(availableLineItems);
const vehicle = this.order.vehicle;
//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=0` +
`&ZipCode=${zipCodeToUse}` +
`${availableLineItemsFormattedForRequest}`;
const response = await globalMethods
.callHttpClient({
method: endpoints.GetPriceOrderItems.method,
endpoint: `${endpoints.GetPriceOrderItems.url}?${queryString}`
}).catch((error) => {
console.error(error);
return [];
});
availableLineItems = addPricesToLineItems(availableLineItems, response.data.lineItems);
return availableLineItems;
},
getServiceabilityDetails({ serviceZipCode }) {
const lineItemsToSend = this.order.lineItems.supportingItems;
const encodedLineItems = encodeURIComponent(JSON.stringify(lineItemsToSend));
return globalMethods.callHttpClient({
method: endpoints.GetServiceabilityDetails.method,
endpoint: `${endpoints.GetServiceabilityDetails.url}?zip=${serviceZipCode}&lineItems=${encodedLineItems}`
});
},
lookupVehicleByVin(vin) {
return globalMethods.callHttpClient({
method: endpoints.LookupVehicleByVin.method,
endpoint: endpoints.LookupVehicleByVin.url,
payload: {
vin
}
});
},
setVehicle() {
return globalMethods
.callHttpClient({
methods: 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;
});
},
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.city = serviceLocationInfo.city;
this.order.serviceLocation.state = serviceLocationInfo.state;
this.order.serviceLocation.zipCode = serviceLocationInfo.zipCode;
this.order.serviceLocation.zipCodeCtu = serviceLocationInfo.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;
},
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.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.vin = vehicle.vin;
this.order.vehicle.imageUrl = vehicle.imageUrl;
this.order.vehicle.imageVifNumber = vehicle.imageVifNumber;
this.order.vehicle.imageColor = vehicle.imageVifColor;
// added for SSR-290
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] = {};
this.applicationUser.pageData[issPageValues.VEHICLE_PARTS] = {};
this.applicationUser.pageData[issPageValues.MOLDING_QUESTIONS] = {};
this.applicationUser.pageData[issPageValues.CAPABILITY_QUESTIONS] = {};
},
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;
},
resetMoldingAndCapabilityQuestionAnswersIfNeeded(matchedParts) {
const partsOrQuestionsDataToCompareWith =
this.pageData(issPageValues.MOLDING_QUESTIONS)?.partsOrQuestions ??
this.pageData(issPageValues.CAPABILITY_QUESTIONS)?.partsOrQuestions ??
[];
const previouslySelectedPartNumbers = getAllPartNumbers(partsOrQuestionsDataToCompareWith);
const currentlySelectedPartNumbers = getAllPartNumbers(matchedParts);
const haveSelectedVehiclePartsChanged =
previouslySelectedPartNumbers !== currentlySelectedPartNumbers;
if (haveSelectedVehiclePartsChanged) {
//was updateGlassParts, added dependencies for SSR-290
this.resetPartsAndDependencies();
this.updateMoldingQuestionAnswers(null);
this.updateCapabilityQuestionAnswers(null);
this.updatePageData({ page: issPageValues.MOLDING_QUESTIONS, data: {} });
this.updatePageData({ page: issPageValues.CAPABILITY_QUESTIONS, data: {} });
}
},
resetISSConfigState() {
this.issConfig.clientName = 'Generic Insurance';
this.issConfig.clientDisplayName = 'Generic Insurance';
this.issConfig.accountNumber = 0;
this.issConfig.styleSheet = '';
this.issConfig.isCoverageEnabled = false;
this.issConfig.isAuthenticated = false;
this.issConfig.enableTPAFlow = false;
this.issConfig.returnURL = null;
this.issConfig.returnURL2 = null;
this.issConfig.disabledFields.policyNumber = false;
this.issConfig.disabledFields.policyZipCode = false;
},
updateVehicleYear(year) {
if(this.order.vehicle.year !== year)
{
this.resetVehicleState();
// was resetDamageState, added dependencies for SSR-290
this.resetDamageAndDependencies();
this.order.vehicle.year = year;
}
},
updateVehicleMake(make) {
if(this.order.vehicle.make !== make)
{
const year = this.order.vehicle.year;
this.resetVehicleState();
// was resetDamageState, added dependencies for SSR-290
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.year;
const make = this.order.vehicle.make;
this.resetVehicleState();
// was resetDamageState, added dependencies for SSR-290
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.year;
const make = this.order.vehicle.make;
const model = this.order.vehicle.model;
this.resetVehicleState();
// was resetDamageState, added dependencies for SSR-290
this.resetDamageAndDependencies();
this.order.vehicle.year = year;
this.order.vehicle.make = make;
this.order.vehicle.model = model;
this.order.vehicle.style = style;
}
},
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) ? 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;
},
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.updateGlassParts(null);
this.updateMoldingQuestionAnswers(null);
this.updateCapabilityQuestionAnswers(null);
// Added for SSR-290
this.resetSupportingItemsState();
this.resetVapsState();
this.updatePageData({ page: issPageValues.VEHICLE_PARTS, data: {} });
this.updatePageData({ page: issPageValues.MOLDING_QUESTIONS, data: {} });
this.updatePageData({ page: issPageValues.CAPABILITY_QUESTIONS, data: {} });
}
//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) {
// was updateGlassParts(null), added dependencies for SSR-290
this.resetPartsAndDependencies();
this.updateCapabilityQuestionAnswers(null);
this.updatePageData({ page: issPageValues.CAPABILITY_QUESTIONS, data: {} });
}
// 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) {
// was updateGlassPars(null), added dependencies for SSR-290
this.resetPartsAndDependencies();
}
// Save new values
this.updateCapabilityQuestionAnswers(capabilityQuestionAnswersArray);
},
saveGlassParts(glassParts) {
this.order.lineItems.glassParts = glassParts;
},
saveSupportingItems(supportingItems) {
this.order.lineItems.supportingItems = supportingItems;
},
saveVaps(vaps) {
this.order.lineItems.vaps = vaps;
},
saveProviderPreferenceData(data){
this.updatePageData({ page: issPageValues.PROVIDER_PREFERENCE, data: 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;
}
},
// Analytics Actions
logExperimentExposure({ userId, sessionKey, pageName, experiment }) {
return globalMethods.callHttpClient({
method: endpoints.LogExperimentExposureIfAssigned.method,
endpoint: endpoints.LogExperimentExposureIfAssigned.url,
payload: {
experimentForLogging: {
userId: 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: sessionKey,
pageName: pageName
}
}
});
},
logPageView({ userId, sessionKey, pageName, sessionId, action, event, shouldUseSessionId, experimentsForUser }) {
const payload = {
userId: userId,
sessionKey: sessionKey,
sessionId: sessionId,
pageName: pageName,
applicationName: applicationConfig.APPLICATION_NAME,
action: action,
event: event,
shouldUseSessionId: shouldUseSessionId,
experimentsForUser: experimentsForUser
};
return globalMethods.callHttpClient({
method: endpoints.LogPageView.method,
endpoint: endpoints.LogPageView.url,
payload: payload,
logApiCall: false
}).then(
(response) => {
return 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: userId,
sessionKey: sessionKey,
sessionId: sessionId,
pageName: pageName,
applicationName: applicationConfig.APPLICATION_NAME,
category: category,
action: action,
label: label,
value: value,
shouldUseSessionId: shouldUseSessionId,
experimentsForUser: experimentsForUser
};
return globalMethods.callHttpClient({
method: endpoints.LogCustomEvent.method,
endpoint: endpoints.LogCustomEvent.url,
payload: payload,
logApiCall: false
}).then(
(response) => {
return response;
},
(error) => {
console.log('Analytics Service Error: ' + error.data);
}
);
},
initializeSession({ userId, sessionId, userAgent, referrer }) {
const payload = {
applicationName: applicationConfig.APPLICATION_NAME,
userId: userId,
deviceId: userId,
sessionId: sessionId,
userAgent: userAgent,
operatorId: 'WEB',
userName: 'SafeliteISS',
referrer: referrer
};
return globalMethods.callHttpClient({
method: endpoints.InitializeSession.method,
endpoint: endpoints.InitializeSession.url,
payload: payload,
logApiCall: false
}).then(
(response) => {
return 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;
},
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: userId,
triggerEvent: triggerEvent,
triggerValue: triggerValue,
experimentOrder: this.experimentOrder
};
const response = await globalMethods.callHttpClient({
method: endpoints.RunExperimentsForTrigger.method,
endpoint: endpoints.RunExperimentsForTrigger.url,
payload: payload
});
this.updateExperiments(response.data.experiments);
},
async validateZip({ zip }) {
return await globalMethods.callHttpClient({
methods: endpoints.ValidateZip.method,
endpoint: `${endpoints.ValidateZip.url}/${zip}`
});
},
async validateClientTag(clientTag) {
return await globalMethods.callHttpClient({
methods: endpoints.ValidateClientTag.method,
endpoint: `${endpoints.ValidateClientTag.url}/${clientTag}`
});
},
saveServiceLocation(serviceLocationInfo) {
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
)
{
this.resetRegistrationAndDependencies();
if (!isSelectedGlassAvailableForVehicle) {
this.resetDamageState();
this.resetGlassPartsState();
}
//Save new values
this.updateRegistration(registrationInfo);
};
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();
}
},
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'
);
} else {
// Has 'requiresRecalibration' but no 'recalibrationType' at all
return true;
}
} else {
// 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;
else if (a[propertyName] > b[propertyName]) return 1;
else return 0;
});
}
function convertGlassPieceNamingForApi(glassArray) {
if (!glassArray || glassArray.length === 0) return [];
// check if array already converted. (likely when a session has been saved previously and then reloaded)
if (glassArray[0].location !== undefined) {
return glassArray;
}
const converted = [];
glassArray.forEach((glass) => {
converted.push({
location: glass.glassLocation,
name: glass.glassName
});
});
return converted;
}
function convertResultsForApi(resultsArray) {
if (!resultsArray) return [];
const converted = [];
resultsArray.forEach((answer) => {
converted.push({
location: answer.glassLocation,
name: answer.glassName,
result: answer.result
});
});
return converted;
}
function convertGlassPieceNamingFromApi(glassArray) {
glassArray.forEach((glass) => {
glass.glassLocation = glass.glassPiece.location;
glass.glassName = glass.glassPiece.name;
delete glass.glassPiece;
return glass;
});
return glassArray;
}
function getAllPartNumbers(partsOrQuestions) {
return partsOrQuestions[0]?.parts
? [...partsOrQuestions]
.map((glass) => glass.parts)
.flat()
.map((part) => part.partNumber)
.filter((partNumber) => !partNumber.toUpperCase().includes('FEE'))
.sort()
.join(',')
: [];
}
function addPricesToLineItems(lineItems, pricingLineItems) {
lineItems.forEach((lineItem) => {
const lineItemIndex = pricingLineItems.findIndex(
(pricingLineItem) => pricingLineItem.partNumber === lineItem.partNumber
);
if (lineItem.childParts) {
addPricesToLineItems(lineItem.childParts, pricingLineItems);
}
const pricedLineItem = pricingLineItems.splice(lineItemIndex, 1)[0];
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('');
}