Merge pull request #54 from Safelite/feature/Digital/SSR-122
Feature/digital/ssr 122
This commit is contained in:
commit
6fa032871e
5 changed files with 307 additions and 69 deletions
|
|
@ -112,9 +112,11 @@ describe("analyticsMixin.js", () => {
|
||||||
// Assert
|
// Assert
|
||||||
expect(expectedDataLayer).toEqual(expect.arrayContaining(window.dataLayer));
|
expect(expectedDataLayer).toEqual(expect.arrayContaining(window.dataLayer));
|
||||||
});
|
});
|
||||||
/*
|
|
||||||
test("Experiments, should push to dataLayer with default Google Custom Dimension Index", () => {
|
test("Experiments, should push to dataLayer with default Google Custom Dimension Index", () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
|
const store = useMainStore();
|
||||||
|
|
||||||
window.dataLayer = [];
|
window.dataLayer = [];
|
||||||
|
|
||||||
const mockExperimentData = [
|
const mockExperimentData = [
|
||||||
|
|
@ -125,26 +127,7 @@ describe("analyticsMixin.js", () => {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// Mock store
|
store.applicationUserObj.experiments = mockExperimentData;
|
||||||
jest.mock(
|
|
||||||
"@/store",
|
|
||||||
() => {
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
{ virtual: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
useMainStore.getters = {
|
|
||||||
applicationUserObj: {
|
|
||||||
experiments: [
|
|
||||||
{
|
|
||||||
settings: {},
|
|
||||||
variationName: "test",
|
|
||||||
universeName: "testUniverse",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
analyticsMixin.methods.pushExperimentsToDataLayer(mockExperimentData);
|
analyticsMixin.methods.pushExperimentsToDataLayer(mockExperimentData);
|
||||||
|
|
@ -163,6 +146,8 @@ describe("analyticsMixin.js", () => {
|
||||||
|
|
||||||
test("Experiments, should push to dataLayer with custom Google Custom Dimension Index", () => {
|
test("Experiments, should push to dataLayer with custom Google Custom Dimension Index", () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
|
const store = useMainStore();
|
||||||
|
|
||||||
window.dataLayer = [];
|
window.dataLayer = [];
|
||||||
|
|
||||||
const mockExperimentData = [
|
const mockExperimentData = [
|
||||||
|
|
@ -173,26 +158,7 @@ describe("analyticsMixin.js", () => {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// Mock store
|
store.applicationUserObj.experiments = mockExperimentData;
|
||||||
jest.mock(
|
|
||||||
"@/store",
|
|
||||||
() => {
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
{ virtual: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
useMainStore.getters = {
|
|
||||||
applicationUserObj: {
|
|
||||||
experiments: [
|
|
||||||
{
|
|
||||||
settings: { "Google Custom Dimension Index": "5" },
|
|
||||||
variationName: "test",
|
|
||||||
universeName: "testUniverse",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
analyticsMixin.methods.pushExperimentsToDataLayer(mockExperimentData);
|
analyticsMixin.methods.pushExperimentsToDataLayer(mockExperimentData);
|
||||||
|
|
@ -208,7 +174,7 @@ describe("analyticsMixin.js", () => {
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
*/
|
|
||||||
test("Obj is not null after action prepended", () => {
|
test("Obj is not null after action prepended", () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const obj = { baseMethodName: "testMethodName", data: "testData" };
|
const obj = { baseMethodName: "testMethodName", data: "testData" };
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,14 @@ import { useMainStore } from "@/store";
|
||||||
export default {
|
export default {
|
||||||
methods: {
|
methods: {
|
||||||
hasSettingEqualTo(settingName, settingValue) {
|
hasSettingEqualTo(settingName, settingValue) {
|
||||||
return useMainStore.experimentSettings[settingName] == settingValue;
|
return useMainStore().experimentSettings[settingName] == settingValue;
|
||||||
},
|
},
|
||||||
hasSetting(settingName) {
|
hasSetting(settingName) {
|
||||||
return Object.hasOwn( useMainStore.experimentSettings, settingName);
|
return Object.hasOwn( useMainStore().experimentSettings, settingName);
|
||||||
},
|
},
|
||||||
getSettingValue(settingName) {
|
getSettingValue(settingName) {
|
||||||
return this.hasSetting(settingName)
|
return this.hasSetting(settingName)
|
||||||
? useMainStore.experimentSettings[settingName]
|
? useMainStore().experimentSettings[settingName]
|
||||||
: null;
|
: null;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
155
src/mixins/experiment-mixin.spec.js
Normal file
155
src/mixins/experiment-mixin.spec.js
Normal file
|
|
@ -0,0 +1,155 @@
|
||||||
|
import experimentMixin from "@/mixins/experiment-mixin";
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
import { useMainStore } from "@/store";
|
||||||
|
|
||||||
|
describe("experiment-mixin", () => {
|
||||||
|
describe("hasSettingEqualTo", () => {
|
||||||
|
test("setting exists and value matches => return true", () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = wrapper.vm.hasSettingEqualTo("Setting2", "Value2");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("setting exists and value does not match => return false", () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = wrapper.vm.hasSettingEqualTo("Setting2", "Value3");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("setting does not exist => return false", () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = wrapper.vm.hasSettingEqualTo("SettingBoogly", "Woogly");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("there are no settings => return false", () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({ experimentSettings: {} });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = wrapper.vm.hasSettingEqualTo("Setting2", "Value3");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toEqual(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("hasSetting", () => {
|
||||||
|
test("has setting => return true", () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = wrapper.vm.hasSetting("Setting4");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("does not have setting => return false", () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = wrapper.vm.hasSetting("BooglyWoogly");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("experimentSettings is empty => return false", () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({ experimentSettings: {} });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = wrapper.vm.hasSetting("Setting4");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toEqual(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("getSettingValue", () => {
|
||||||
|
test("has setting => return correct value", () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = wrapper.vm.getSettingValue("Setting3");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toEqual("Value3");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("does not have setting => return null", () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = wrapper.vm.getSettingValue("Hello");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("experimentSettings is empty => return null", () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({ experimentSettings: {} });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = wrapper.vm.getSettingValue("Hello");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function setupMocks({ experimentSettings }) {
|
||||||
|
const store = useMainStore();
|
||||||
|
const mocks = getMountOptions({});
|
||||||
|
|
||||||
|
const testExperimentSettings = {
|
||||||
|
Setting1: "Value1",
|
||||||
|
Setting2: "Value2",
|
||||||
|
Setting3: "Value3",
|
||||||
|
Setting4: "Value1",
|
||||||
|
Setting5: "Value2",
|
||||||
|
Setting6: "Value3",
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockExperimentData = [
|
||||||
|
{
|
||||||
|
settings: experimentSettings ?? testExperimentSettings,
|
||||||
|
variationName: "test",
|
||||||
|
universeName: "testUniverse",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
store.applicationUser.experiments = mockExperimentData;
|
||||||
|
|
||||||
|
const mockComponent = {
|
||||||
|
template: "<div></div>",
|
||||||
|
mixins: [experimentMixin],
|
||||||
|
};
|
||||||
|
|
||||||
|
const wrapper = shallowMount(mockComponent, mocks);
|
||||||
|
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,13 @@ import { routingTable } from "@/router/router-constants/routing-table";
|
||||||
import { useMainStore } from '@/store';
|
import { useMainStore } from '@/store';
|
||||||
import eventBus from "@/helpers/event-bus/event-bus";
|
import eventBus from "@/helpers/event-bus/event-bus";
|
||||||
import { globalEvents, globalEventTypes } from "@/constants/events";
|
import { globalEvents, globalEventTypes } from "@/constants/events";
|
||||||
|
import {
|
||||||
|
getDeviceIdValue,
|
||||||
|
updateOrCreateISSCookie,
|
||||||
|
updateSessionIdCookie,
|
||||||
|
} from "@/helpers/cookie-helper";
|
||||||
|
import { experimentTriggers } from "@/constants/experiments";
|
||||||
|
import { applicationConfig } from "@/constants/application-config";
|
||||||
|
|
||||||
import analyticsMixin from "@/mixins/analytics-mixin";
|
import analyticsMixin from "@/mixins/analytics-mixin";
|
||||||
|
|
||||||
|
|
@ -16,6 +23,17 @@ const routes = [
|
||||||
try {
|
try {
|
||||||
to.query.issPage = !to.query.issPage ? issPageValues.VEHICLE_YEAR : to.query.issPage;
|
to.query.issPage = !to.query.issPage ? issPageValues.VEHICLE_YEAR : to.query.issPage;
|
||||||
|
|
||||||
|
if (analyticsMixin.methods.noSession()) {
|
||||||
|
await analyticsMixin.methods.initSession();
|
||||||
|
} else {
|
||||||
|
updateSessionIdCookie();
|
||||||
|
}
|
||||||
|
|
||||||
|
await runExperiments(to.query.issPage);
|
||||||
|
|
||||||
|
// Process ISS cookie.
|
||||||
|
updateOrCreateISSCookie();
|
||||||
|
|
||||||
if (router.hasRoute(to.query.issPage)) {
|
if (router.hasRoute(to.query.issPage)) {
|
||||||
return next({ name: to.query.issPage, query: to.query, params: to.params });
|
return next({ name: to.query.issPage, query: to.query, params: to.params });
|
||||||
}
|
}
|
||||||
|
|
@ -184,4 +202,23 @@ function GoToStartOn404(next) {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Run SiteEntry and PageEntry triggers for experiments
|
||||||
|
async function runExperiments(nextPage) {
|
||||||
|
const store = useMainStore();
|
||||||
|
|
||||||
|
if (!store.applicationUser.triggeredSiteEntry) {
|
||||||
|
await store.runExperimentsForTrigger({
|
||||||
|
userId: getDeviceIdValue(),
|
||||||
|
triggerEvent: experimentTriggers.SITE_ENTRY,
|
||||||
|
triggerValue: applicationConfig.SITE_ENTRY_TRIGGER_VALUE,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await store.runExperimentsForTrigger({
|
||||||
|
userId: getDeviceIdValue(),
|
||||||
|
triggerEvent: experimentTriggers.PAGE_ENTRY,
|
||||||
|
triggerValue: nextPage,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|
@ -2,8 +2,10 @@ import { defineStore } from "pinia";
|
||||||
import { endpoints } from "@/constants/endpoints.js";
|
import { endpoints } from "@/constants/endpoints.js";
|
||||||
import { getDateForSavedSessionTimeout } from "@/helpers/session-helper";
|
import { getDateForSavedSessionTimeout } from "@/helpers/session-helper";
|
||||||
import globalMethods from "@/global-methods";
|
import globalMethods from "@/global-methods";
|
||||||
|
import { experimentTriggers } from "@/constants/experiments";
|
||||||
import { applicationConfig } from "@/constants/application-config";
|
import { applicationConfig } from "@/constants/application-config";
|
||||||
import { issPageValues } from "@/router/router-constants/issPage-values";
|
import { issPageValues } from "@/router/router-constants/issPage-values";
|
||||||
|
import { damageLocationsSelected } from "@/constants/damage-locations-selected";
|
||||||
|
|
||||||
const storeId = 'main';
|
const storeId = 'main';
|
||||||
|
|
||||||
|
|
@ -42,6 +44,18 @@ const getDefaultState = () => {
|
||||||
lineItems: {
|
lineItems: {
|
||||||
glassParts: null,
|
glassParts: null,
|
||||||
},
|
},
|
||||||
|
payment: {
|
||||||
|
isInsurance: true,
|
||||||
|
insuranceCoverage: {
|
||||||
|
isVerified: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
serviceLocation: {
|
||||||
|
address: null,
|
||||||
|
city: null,
|
||||||
|
state: null,
|
||||||
|
zipCode: null,
|
||||||
|
},
|
||||||
referralNumber: null,
|
referralNumber: null,
|
||||||
referralDate: null,
|
referralDate: null,
|
||||||
accountNumber: 0,
|
accountNumber: 0,
|
||||||
|
|
@ -85,38 +99,37 @@ export const useMainStore = defineStore({
|
||||||
},
|
},
|
||||||
experimentOrder: (state) => {
|
experimentOrder: (state) => {
|
||||||
return {
|
return {
|
||||||
funnelVehicleYear: state.order.vehicle.year,
|
issVehicleYear: state.order.vehicle.year,
|
||||||
funnelVehicleMake: state.order.vehicle.make,
|
issVehicleMake: state.order.vehicle.make,
|
||||||
funnelVehicleModel: state.order.vehicle.model,
|
issVehicleModel: state.order.vehicle.model,
|
||||||
funnelVehicleStyle: state.order.vehicle.style,
|
issVehicleStyle: state.order.vehicle.style,
|
||||||
funnelIsRepair: state.order.damage.isRepair,
|
issIsRepair: state.order.damage.isRepair,
|
||||||
funnelNumberOfChips: state.order.damage.numberOfChips,
|
issNumberOfChips: state.order.damage.numberOfChips,
|
||||||
funnelCarId: state.order.vehicle.carId,
|
issCarId: state.order.vehicle.carId,
|
||||||
funnelServiceCity: state.order.serviceLocation.city,
|
issServiceCity: state.order.serviceLocation.city,
|
||||||
funnelServiceState: state.order.serviceLocation.state,
|
issServiceState: state.order.serviceLocation.state,
|
||||||
funnelServiceZipCode: state.order.serviceLocation.zipCode,
|
issServiceZipCode: state.order.serviceLocation.zipCode,
|
||||||
funnelParentAccountNumber: state.order.accountNumber,
|
issParentAccountNumber: state.order.accountNumber,
|
||||||
funnelIsCoverageVerified: state.order.payment.insuranceCoverage.isVerified,
|
issIsCoverageVerified: state.order.payment.insuranceCoverage.isVerified,
|
||||||
funnelHasRecalibrationPart: getHasRecalibrationPart(state),
|
issHasRecalibrationPart: getHasRecalibrationPart(state),
|
||||||
funnelSelectedMultiGlass: state.order.damage.glassToReplace?.length > 1,
|
issSelectedMultiGlass: state.order.damage.glassToReplace?.length > 1,
|
||||||
funnelSelectedWindshieldGlass: getNonFalseValuesOfPropertyInArrayOfObjects(
|
issSelectedWindshieldGlass: getNonFalseValuesOfPropertyInArrayOfObjects(
|
||||||
state.order.damage.glassToReplace,
|
state.order.damage.glassToReplace,
|
||||||
"glassLocation"
|
"glassLocation"
|
||||||
).includes(damageLocationsSelected.WINDSHIELD),
|
).includes(damageLocationsSelected.WINDSHIELD),
|
||||||
funnelSelectedBackGlass: getNonFalseValuesOfPropertyInArrayOfObjects(
|
issSelectedBackGlass: getNonFalseValuesOfPropertyInArrayOfObjects(
|
||||||
state.order.damage.glassToReplace,
|
state.order.damage.glassToReplace,
|
||||||
"glassLocation"
|
"glassLocation"
|
||||||
).includes(damageLocationsSelected.REAR),
|
).includes(damageLocationsSelected.REAR),
|
||||||
funnelSelectedDriverSideGlass: getNonFalseValuesOfPropertyInArrayOfObjects(
|
issSelectedDriverSideGlass: getNonFalseValuesOfPropertyInArrayOfObjects(
|
||||||
state.order.damage.glassToReplace,
|
state.order.damage.glassToReplace,
|
||||||
"glassLocation"
|
"glassLocation"
|
||||||
).includes(damageLocationsSelected.DRIVER),
|
).includes(damageLocationsSelected.DRIVER),
|
||||||
funnelSelectedPassengerSideGlass: getNonFalseValuesOfPropertyInArrayOfObjects(
|
issSelectedPassengerSideGlass: getNonFalseValuesOfPropertyInArrayOfObjects(
|
||||||
state.order.damage.glassToReplace,
|
state.order.damage.glassToReplace,
|
||||||
"glassLocation"
|
"glassLocation"
|
||||||
).includes(damageLocationsSelected.PASSENGER),
|
).includes(damageLocationsSelected.PASSENGER),
|
||||||
|
issOrderPartNumbers: [
|
||||||
funnelOrderPartNumbers: [
|
|
||||||
...getNonFalseValuesOfPropertyInArrayOfObjects(
|
...getNonFalseValuesOfPropertyInArrayOfObjects(
|
||||||
state.order.lineItems.glassParts,
|
state.order.lineItems.glassParts,
|
||||||
"partNumber"
|
"partNumber"
|
||||||
|
|
@ -127,7 +140,7 @@ export const useMainStore = defineStore({
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
||||||
funnelOrderPartTypes: [
|
issOrderPartTypes: [
|
||||||
...getNonFalseValuesOfPropertyInArrayOfObjects(
|
...getNonFalseValuesOfPropertyInArrayOfObjects(
|
||||||
state.order.lineItems.glassParts,
|
state.order.lineItems.glassParts,
|
||||||
"recalibrationType"
|
"recalibrationType"
|
||||||
|
|
@ -483,6 +496,13 @@ export const useMainStore = defineStore({
|
||||||
this.applicationUser.lastPageVisited = lastPageVisited;
|
this.applicationUser.lastPageVisited = lastPageVisited;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
updateExperiments(experiments) {
|
||||||
|
this.applicationUser.experiments = experiments;
|
||||||
|
},
|
||||||
|
updateTriggeredSiteEntry(wasSiteEntryTriggered) {
|
||||||
|
this.applicationUser.triggeredSiteEntry = wasSiteEntryTriggered;
|
||||||
|
},
|
||||||
|
|
||||||
GetExperimentsByUser(userId) {
|
GetExperimentsByUser(userId) {
|
||||||
return globalMethods.callHttpClient({
|
return globalMethods.callHttpClient({
|
||||||
method: endpoints.GetExperimentsByUser.method,
|
method: endpoints.GetExperimentsByUser.method,
|
||||||
|
|
@ -491,6 +511,66 @@ export const useMainStore = defineStore({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async runExperimentsForTrigger({ userId, triggerEvent, triggerValue }) {
|
||||||
|
if (triggerEvent == experimentTriggers.SITE_ENTRY) {
|
||||||
|
this.updateTriggeredSiteEntry(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
var 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);
|
||||||
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
persist: true
|
persist: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Private Functions
|
||||||
|
|
||||||
|
function getHasRecalibrationPart(state) {
|
||||||
|
var hasRequiresRecalibration =
|
||||||
|
getNonFalseValuesOfPropertyInArrayOfObjects(
|
||||||
|
state.order.lineItems.glassParts,
|
||||||
|
"requiresRecalibration"
|
||||||
|
)?.length > 0;
|
||||||
|
var hasRecalibrationType =
|
||||||
|
getNonFalseValuesOfPropertyInArrayOfObjects(
|
||||||
|
state.order.lineItems.glassParts,
|
||||||
|
"recalibrationType"
|
||||||
|
)?.length > 0;
|
||||||
|
|
||||||
|
if (hasRequiresRecalibration) {
|
||||||
|
if (hasRecalibrationType) {
|
||||||
|
// Has both 'requiresRecalibration' and 'recalibrationType' and 'recalibrationType'
|
||||||
|
return (
|
||||||
|
getNonFalseValuesOfPropertyInArrayOfObjects(
|
||||||
|
state.order.lineItems.glassParts,
|
||||||
|
"recalibrationType"
|
||||||
|
)[0].toLowerCase() != "unknown"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Has 'requiresRecalibration' but no 'recalibrationType' at all
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Does not have 'requiresRecalibration'
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNonFalseValuesOfPropertyInArrayOfObjects(array, propertyName) {
|
||||||
|
return (array ?? []).map((x) => x[propertyName]).filter((x) => x);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue