From bc43b73fc6f9c095f32e97c3a16c66d756a53c9a Mon Sep 17 00:00:00 2001 From: ailZhou <127151429+ailZhou@users.noreply.github.com> Date: Thu, 19 Sep 2024 14:59:31 -0400 Subject: [PATCH] GV Refactor - validateRateNotZero (#2444) --- .../ComplexAtLeastOneRateComplete/index.tsx | 66 ------- .../measures/2021/globalValidations/index.ts | 2 +- .../validateRateNotZero/index.test.ts | 171 ----------------- .../validateRateNotZero/index.ts | 80 -------- .../2022/shared/globalValidations/index.ts | 2 +- .../validateRateNotZero/index.test.ts | 172 ------------------ .../validateRateNotZero/index.ts | 79 -------- .../2022/shared/util/validationsMock.tsx | 2 +- .../2023/shared/globalValidations/index.ts | 2 +- .../validateRateNotZero/index.ts | 79 -------- .../2023/shared/util/validationsMock.tsx | 2 +- .../2024/shared/globalValidations/index.ts | 2 +- .../validateRateNotZero/index.test.ts | 167 ----------------- .../2024/shared/util/validationsMock.tsx | 2 +- .../validateRateNotZero/index.test.ts | 0 .../validateRateNotZero/index.ts | 2 +- 16 files changed, 8 insertions(+), 822 deletions(-) delete mode 100644 services/ui-src/src/measures/2021/globalValidations/ComplexValidations/ComplexAtLeastOneRateComplete/index.tsx delete mode 100644 services/ui-src/src/measures/2021/globalValidations/validateRateNotZero/index.test.ts delete mode 100644 services/ui-src/src/measures/2021/globalValidations/validateRateNotZero/index.ts delete mode 100644 services/ui-src/src/measures/2022/shared/globalValidations/validateRateNotZero/index.test.ts delete mode 100644 services/ui-src/src/measures/2022/shared/globalValidations/validateRateNotZero/index.ts delete mode 100644 services/ui-src/src/measures/2023/shared/globalValidations/validateRateNotZero/index.ts delete mode 100644 services/ui-src/src/measures/2024/shared/globalValidations/validateRateNotZero/index.test.ts rename services/ui-src/src/{measures/2023 => }/shared/globalValidations/validateRateNotZero/index.test.ts (100%) rename services/ui-src/src/{measures/2024 => }/shared/globalValidations/validateRateNotZero/index.ts (98%) diff --git a/services/ui-src/src/measures/2021/globalValidations/ComplexValidations/ComplexAtLeastOneRateComplete/index.tsx b/services/ui-src/src/measures/2021/globalValidations/ComplexValidations/ComplexAtLeastOneRateComplete/index.tsx deleted file mode 100644 index ab62cab4aa..0000000000 --- a/services/ui-src/src/measures/2021/globalValidations/ComplexValidations/ComplexAtLeastOneRateComplete/index.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { validatePartialRateCompletionPM } from "shared/globalValidations/validatePartialRateCompletion"; - -/* At least one NDR set must be complete (OPM or PM) */ -export const ComplexAtLeastOneRateComplete = ( - performanceMeasureArray: any, - OPM: any, - errorLocation: string = "Performance Measure/Other Performance Measure" -) => { - let error = true; - let partialError = false; - let errorArray: FormError[] = []; - - // Check OPM first - OPM && - OPM.forEach((measure: any) => { - if (measure?.rate && measure?.rate?.[0]?.rate) { - error = false; - } - }); - - // Check regular Performance Measures if cannot validate OPM - // For each Performance Measure - // Check that the performance measure has a field representation for each age groups - // Check that each field has a "value" and it is not an empty string - // For a complete measure the sum of the booleans will equal the length of the age groups - for (const category of performanceMeasureArray) { - for (const qualifier of category) { - const qualComplete = qualifier.fields.every( - (field: { value: string; label: string }) => { - return field.value !== undefined && field.value !== ""; - } - ); - if ( - !qualComplete && - qualifier.fields.some((field: { value?: string; label?: string }) => { - return !!(field?.value !== undefined && field?.value !== ""); - }) - ) { - partialError = true; - } - if (qualComplete) { - error = false; - } - } - } - - if (partialError) { - errorArray.push({ - errorLocation: errorLocation, - errorMessage: `Should not have partially filled data sets.`, - }); - } - - if (error) { - errorArray.push({ - errorLocation: errorLocation, - errorMessage: "At least one set of fields must be complete.", - }); - } - - if (OPM) { - errorArray.push(...validatePartialRateCompletionPM([], OPM, [])); - } - - return errorArray; -}; diff --git a/services/ui-src/src/measures/2021/globalValidations/index.ts b/services/ui-src/src/measures/2021/globalValidations/index.ts index 6b97e90379..45bff15fb1 100644 --- a/services/ui-src/src/measures/2021/globalValidations/index.ts +++ b/services/ui-src/src/measures/2021/globalValidations/index.ts @@ -9,7 +9,7 @@ export * from "shared/globalValidations/validateBothDatesInRange"; export * from "shared/globalValidations/validateDualPopInformation"; export * from "shared/globalValidations/validateEqualCategoryDenominators"; export * from "shared/globalValidations/validateEqualQualifierDenominators"; -export * from "./validateRateNotZero"; +export * from "shared/globalValidations/validateRateNotZero"; export * from "./validateRateZero"; export * from "shared/globalValidations/validateNumeratorsLessThanDenominators"; export * from "shared/globalValidations/validateOneCatRateHigherThanOtherCat"; diff --git a/services/ui-src/src/measures/2021/globalValidations/validateRateNotZero/index.test.ts b/services/ui-src/src/measures/2021/globalValidations/validateRateNotZero/index.test.ts deleted file mode 100644 index df76b4dfa5..0000000000 --- a/services/ui-src/src/measures/2021/globalValidations/validateRateNotZero/index.test.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { LabelData } from "utils"; -import { validateRateNotZeroOMS, validateRateNotZeroPM } from "."; -import { - generateOmsQualifierRateData, - locationDictionary, - manualZeroRate, - manualNonZeroRate, - simpleRate, - partialRate, - generateOtherPerformanceMeasureData, -} from "utils/testUtils/validationHelpers"; - -jest.mock("utils/getLabelText", () => ({ - isLegacyLabel: () => true, -})); - -describe("Testing Non-Zero/No Zero Numerator/Rate Validation", () => { - const categories: LabelData[] = [ - { id: "Test Cat 1", label: "Test Cat 1", text: "Test Cat 1" }, - { id: "Test Cat 2", label: "Test Cat 2", text: "Test Cat 2" }, - ]; - const qualifiers: LabelData[] = [ - { id: "Test Qual 1", label: "Test Qual 1", text: "Test Qual 1" }, - { id: "Test Qual 2", label: "Test Qual 2", text: "Test Qual 2" }, - ]; - const baseOMSInfo = { - categories, - qualifiers, - locationDictionary, - isOPM: false, - label: ["TestLabel"], - }; - - // PM - describe("PM/OPM Validation", () => { - it("should return NO errors", () => { - const errors = validateRateNotZeroPM( - [[simpleRate, simpleRate]], - undefined, - qualifiers - ); - - expect(errors).toHaveLength(0); - }); - - it("should have NO error for zero numerator but rate non-zero - Hybrid", () => { - const errors = validateRateNotZeroPM( - [], - generateOtherPerformanceMeasureData([ - manualNonZeroRate, - manualNonZeroRate, - manualNonZeroRate, - ]), - qualifiers - ); - - expect(errors).toHaveLength(0); - }); - - it("should have error for zero rate but numerator non-zero", () => { - const errors = validateRateNotZeroPM( - [ - [manualZeroRate, manualZeroRate], - [manualZeroRate, manualZeroRate], - ], - undefined, - qualifiers - ); - - expect(errors).toHaveLength(1); - expect(errors[0].errorLocation).toBe( - `Performance Measure/Other Performance Measure` - ); - expect(errors[0].errorMessage).toBe( - "Rate should not be 0 if numerator and denominator are not 0. If the calculated rate is less than 0.5, disregard this validation." - ); - }); - - it("should have error for zero rate but numerator non-zero - OPM", () => { - const errors = validateRateNotZeroPM( - [], - generateOtherPerformanceMeasureData([ - manualZeroRate, - manualZeroRate, - manualZeroRate, - ]), - qualifiers - ); - - expect(errors).toHaveLength(1); - expect(errors[0].errorLocation).toBe( - `Performance Measure/Other Performance Measure` - ); - expect(errors[0].errorMessage).toBe( - "Rate should not be 0 if numerator and denominator are not 0. If the calculated rate is less than 0.5, disregard this validation." - ); - }); - - it("should NOT have error from empty rate value", () => { - const errors = validateRateNotZeroPM( - [ - [partialRate, partialRate], - [partialRate, partialRate], - ], - undefined, - qualifiers - ); - - expect(errors).toHaveLength(0); - }); - - it("Error message text should match provided errorMessage", () => { - const errorMessage = "Another one bites the dust."; - const errors = validateRateNotZeroPM( - [ - [manualZeroRate, manualZeroRate], - [manualZeroRate, manualZeroRate], - ], - undefined, - qualifiers, - errorMessage - ); - - expect(errors).toHaveLength(1); - expect(errors[0].errorLocation).toBe( - `Performance Measure/Other Performance Measure` - ); - expect(errors[0].errorMessage).toBe(errorMessage); - }); - }); - - // OMS - describe("OMS Validation", () => { - it("should have error for zero numerator but rate non-zero", () => { - const data = generateOmsQualifierRateData(categories, qualifiers, [ - manualZeroRate, - manualZeroRate, - ]); - const errors = validateRateNotZeroOMS()({ - ...baseOMSInfo, - rateData: data, - }); - - expect(errors).toHaveLength(1); - expect(errors[0].errorLocation).toContain( - "Optional Measure Stratification: TestLabel" - ); - expect(errors[0].errorMessage).toBe( - "Rate should not be 0 if numerator and denominator are not 0. If the calculated rate is less than 0.5, disregard this validation." - ); - }); - }); - - it("Error message text should match provided errorMessage", () => { - const errorMessage = "Another one bites the dust."; - const data = generateOmsQualifierRateData(categories, qualifiers, [ - manualZeroRate, - manualZeroRate, - ]); - const errors = validateRateNotZeroOMS(errorMessage)({ - ...baseOMSInfo, - rateData: data, - }); - - expect(errors).toHaveLength(1); - expect(errors[0].errorLocation).toContain( - "Optional Measure Stratification: TestLabel" - ); - expect(errors[0].errorMessage).toBe(errorMessage); - }); -}); diff --git a/services/ui-src/src/measures/2021/globalValidations/validateRateNotZero/index.ts b/services/ui-src/src/measures/2021/globalValidations/validateRateNotZero/index.ts deleted file mode 100644 index 97903aa3c0..0000000000 --- a/services/ui-src/src/measures/2021/globalValidations/validateRateNotZero/index.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { - OmsValidationCallback, - FormRateField, - UnifiedValFuncProps as UVFP, -} from "../types"; -import { - convertOmsDataToRateArray, - getOtherPerformanceMeasureRateArray, -} from "../dataDrivenTools"; -import { LabelData } from "utils"; - -export const validationRateNotZero = ({ - location, - rateData, - errorMessage, -}: UVFP) => { - const errorArray: FormError[] = []; - - for (const ratefields of rateData) { - for (const rate of ratefields) { - if (rate && rate.denominator && rate.numerator && rate.rate) { - if ( - parseFloat(rate.numerator) > 0 && - parseFloat(rate.denominator) > 0 && - parseFloat(rate.rate) === 0 - ) { - errorArray.push({ - errorLocation: location, - errorMessage: - errorMessage ?? - "Rate should not be 0 if numerator and denominator are not 0. If the calculated rate is less than 0.5, disregard this validation.", - }); - } - } - } - } - - return errorArray; -}; - -export const validateRateNotZeroOMS = - (errorMessage?: string): OmsValidationCallback => - ({ categories, qualifiers, rateData, label, locationDictionary }) => { - return validationRateNotZero({ - categories, - qualifiers, - location: `Optional Measure Stratification: ${locationDictionary(label)}`, - rateData: convertOmsDataToRateArray(categories, qualifiers, rateData), - errorMessage, - }).filter((v, i, a) => i === 0 || a[0].errorLocation !== v.errorLocation); - }; - -// If a user manually over-rides a rate it must not violate two rules: -// It Must be greater than zero if the Num and Denom are greater than zero -export const validateRateNotZeroPM = ( - performanceMeasureArray: FormRateField[][], - OPM: any, - _qualifiers: LabelData[], - errorMessage?: string -) => { - const errorArray: FormError[] = []; - const location = `Performance Measure/Other Performance Measure`; - const rateDataOPM = getOtherPerformanceMeasureRateArray(OPM); - - const errors = [ - ...validationRateNotZero({ - location, - rateData: performanceMeasureArray, - errorMessage, - }), - ...validationRateNotZero({ - location, - rateData: rateDataOPM, - errorMessage, - }), - ]; - - if (!!errors.length) errorArray.push(errors[0]); - return errorArray; -}; diff --git a/services/ui-src/src/measures/2022/shared/globalValidations/index.ts b/services/ui-src/src/measures/2022/shared/globalValidations/index.ts index 6b97e90379..45bff15fb1 100644 --- a/services/ui-src/src/measures/2022/shared/globalValidations/index.ts +++ b/services/ui-src/src/measures/2022/shared/globalValidations/index.ts @@ -9,7 +9,7 @@ export * from "shared/globalValidations/validateBothDatesInRange"; export * from "shared/globalValidations/validateDualPopInformation"; export * from "shared/globalValidations/validateEqualCategoryDenominators"; export * from "shared/globalValidations/validateEqualQualifierDenominators"; -export * from "./validateRateNotZero"; +export * from "shared/globalValidations/validateRateNotZero"; export * from "./validateRateZero"; export * from "shared/globalValidations/validateNumeratorsLessThanDenominators"; export * from "shared/globalValidations/validateOneCatRateHigherThanOtherCat"; diff --git a/services/ui-src/src/measures/2022/shared/globalValidations/validateRateNotZero/index.test.ts b/services/ui-src/src/measures/2022/shared/globalValidations/validateRateNotZero/index.test.ts deleted file mode 100644 index 90d2af0604..0000000000 --- a/services/ui-src/src/measures/2022/shared/globalValidations/validateRateNotZero/index.test.ts +++ /dev/null @@ -1,172 +0,0 @@ -import { LabelData } from "utils"; -import { validateRateNotZeroOMS, validateRateNotZeroPM } from "."; -import { - generateOmsQualifierRateData, - locationDictionary, - manualZeroRate, - manualNonZeroRate, - simpleRate, - partialRate, - generateOtherPerformanceMeasureData, -} from "utils/testUtils/validationHelpers"; - -jest.mock("utils/getLabelText", () => ({ - isLegacyLabel: () => true, -})); - -describe("Testing Non-Zero/No Zero Numerator/Rate Validation", () => { - const categories: LabelData[] = [ - { id: "Test Cat 1", label: "Test Cat 1", text: "Test Cat 1" }, - { id: "Test Cat 2", label: "Test Cat 2", text: "Test Cat 2" }, - ]; - const qualifiers: LabelData[] = [ - { id: "Test Qual 1", label: "Test Qual 1", text: "Test Qual 1" }, - { id: "Test Qual 2", label: "Test Qual 2", text: "Test Qual 2" }, - ]; - - const baseOMSInfo = { - categories, - qualifiers, - locationDictionary, - isOPM: false, - label: ["TestLabel"], - }; - - // PM - describe("PM/OPM Validation", () => { - it("should return NO errors", () => { - const errors = validateRateNotZeroPM( - [[simpleRate, simpleRate]], - undefined, - qualifiers - ); - - expect(errors).toHaveLength(0); - }); - - it("should have NO error for zero numerator but rate non-zero - Hybrid", () => { - const errors = validateRateNotZeroPM( - [], - generateOtherPerformanceMeasureData([ - manualNonZeroRate, - manualNonZeroRate, - manualNonZeroRate, - ]), - qualifiers - ); - - expect(errors).toHaveLength(0); - }); - - it("should have error for zero rate but numerator non-zero", () => { - const errors = validateRateNotZeroPM( - [ - [manualZeroRate, manualZeroRate], - [manualZeroRate, manualZeroRate], - ], - undefined, - qualifiers - ); - - expect(errors).toHaveLength(1); - expect(errors[0].errorLocation).toBe( - `Performance Measure/Other Performance Measure` - ); - expect(errors[0].errorMessage).toBe( - "Rate should not be 0 if numerator and denominator are not 0. If the calculated rate is less than 0.5, disregard this validation." - ); - }); - - it("should have error for zero rate but numerator non-zero - OPM", () => { - const errors = validateRateNotZeroPM( - [], - generateOtherPerformanceMeasureData([ - manualZeroRate, - manualZeroRate, - manualZeroRate, - ]), - qualifiers - ); - - expect(errors).toHaveLength(1); - expect(errors[0].errorLocation).toBe( - `Performance Measure/Other Performance Measure` - ); - expect(errors[0].errorMessage).toBe( - "Rate should not be 0 if numerator and denominator are not 0. If the calculated rate is less than 0.5, disregard this validation." - ); - }); - - it("should NOT have error from empty rate value", () => { - const errors = validateRateNotZeroPM( - [ - [partialRate, partialRate], - [partialRate, partialRate], - ], - undefined, - qualifiers - ); - - expect(errors).toHaveLength(0); - }); - - it("Error message text should match provided errorMessage", () => { - const errorMessage = "Another one bites the dust."; - const errors = validateRateNotZeroPM( - [ - [manualZeroRate, manualZeroRate], - [manualZeroRate, manualZeroRate], - ], - undefined, - qualifiers, - errorMessage - ); - - expect(errors).toHaveLength(1); - expect(errors[0].errorLocation).toBe( - `Performance Measure/Other Performance Measure` - ); - expect(errors[0].errorMessage).toBe(errorMessage); - }); - }); - - // OMS - describe("OMS Validation", () => { - it("should have error for zero numerator but rate non-zero", () => { - const data = generateOmsQualifierRateData(categories, qualifiers, [ - manualZeroRate, - manualZeroRate, - ]); - const errors = validateRateNotZeroOMS()({ - ...baseOMSInfo, - rateData: data, - }); - - expect(errors).toHaveLength(1); - expect(errors[0].errorLocation).toContain( - "Optional Measure Stratification: TestLabel" - ); - expect(errors[0].errorMessage).toBe( - "Rate should not be 0 if numerator and denominator are not 0. If the calculated rate is less than 0.5, disregard this validation." - ); - }); - }); - - it("Error message text should match provided errorMessage", () => { - const errorMessage = "Another one bites the dust."; - const data = generateOmsQualifierRateData(categories, qualifiers, [ - manualZeroRate, - manualZeroRate, - ]); - const errors = validateRateNotZeroOMS(errorMessage)({ - ...baseOMSInfo, - rateData: data, - }); - - expect(errors).toHaveLength(1); - expect(errors[0].errorLocation).toContain( - "Optional Measure Stratification: TestLabel" - ); - expect(errors[0].errorMessage).toBe(errorMessage); - }); -}); diff --git a/services/ui-src/src/measures/2022/shared/globalValidations/validateRateNotZero/index.ts b/services/ui-src/src/measures/2022/shared/globalValidations/validateRateNotZero/index.ts deleted file mode 100644 index 0e6d6515b9..0000000000 --- a/services/ui-src/src/measures/2022/shared/globalValidations/validateRateNotZero/index.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { - OmsValidationCallback, - FormRateField, - UnifiedValFuncProps as UVFP, -} from "../types"; -import { - convertOmsDataToRateArray, - getOtherPerformanceMeasureRateArray, -} from "../dataDrivenTools"; -import { LabelData } from "utils"; - -export const validationRateNotZero = ({ - location, - rateData, - errorMessage, -}: UVFP) => { - const errorArray: FormError[] = []; - - for (const ratefields of rateData) { - for (const rate of ratefields) { - if (rate && rate.denominator && rate.numerator && rate.rate) { - if ( - parseFloat(rate.numerator) > 0 && - parseFloat(rate.denominator) > 0 && - parseFloat(rate.rate) === 0 - ) { - errorArray.push({ - errorLocation: location, - errorMessage: - errorMessage ?? - "Rate should not be 0 if numerator and denominator are not 0. If the calculated rate is less than 0.5, disregard this validation.", - }); - } - } - } - } - - return errorArray; -}; - -export const validateRateNotZeroOMS = - (errorMessage?: string): OmsValidationCallback => - ({ categories, qualifiers, rateData, label, locationDictionary }) => { - return validationRateNotZero({ - categories, - qualifiers, - location: `Optional Measure Stratification: ${locationDictionary(label)}`, - rateData: convertOmsDataToRateArray(categories, qualifiers, rateData), - errorMessage, - }).filter((v, i, a) => i === 0 || a[0].errorLocation !== v.errorLocation); - }; - -// If a user manually over-rides a rate it must not violate two rules: -// It must be zero if the numerator is zero -export const validateRateNotZeroPM = ( - performanceMeasureArray: FormRateField[][], - OPM: any, - _qualifiers: LabelData[], - errorMessage?: string -) => { - const errorArray: FormError[] = []; - const location = `Performance Measure/Other Performance Measure`; - const rateDataOPM = getOtherPerformanceMeasureRateArray(OPM); - - const errors = [ - ...validationRateNotZero({ - location, - rateData: performanceMeasureArray, - errorMessage, - }), - ...validationRateNotZero({ - location, - rateData: rateDataOPM, - errorMessage, - }), - ]; - if (!!errors.length) errorArray.push(errors[0]); - return errorArray; -}; diff --git a/services/ui-src/src/measures/2022/shared/util/validationsMock.tsx b/services/ui-src/src/measures/2022/shared/util/validationsMock.tsx index 528f1d25cb..4e8a79f46c 100644 --- a/services/ui-src/src/measures/2022/shared/util/validationsMock.tsx +++ b/services/ui-src/src/measures/2022/shared/util/validationsMock.tsx @@ -5,7 +5,7 @@ import * as validateBothDatesInRange from "shared/globalValidations/validateBoth import * as validateDualPopInformation from "shared/globalValidations/validateDualPopInformation"; import * as validateEqualCategoryDenominators from "shared/globalValidations/validateEqualCategoryDenominators"; import * as validateEqualQualifierDenominators from "shared/globalValidations/validateEqualQualifierDenominators"; -import * as validateRateNotZero from "measures/2022/shared/globalValidations/validateRateNotZero"; +import * as validateRateNotZero from "shared/globalValidations/validateRateNotZero"; import * as validateRateZero from "measures/2022/shared/globalValidations/validateRateZero"; import * as validateNumeratorsLessThanDenominators from "shared/globalValidations/validateNumeratorsLessThanDenominators"; import * as validateOneCatRateHigherThanOtherCat from "shared/globalValidations/validateOneCatRateHigherThanOtherCat"; diff --git a/services/ui-src/src/measures/2023/shared/globalValidations/index.ts b/services/ui-src/src/measures/2023/shared/globalValidations/index.ts index 2d750c10ed..540968148a 100644 --- a/services/ui-src/src/measures/2023/shared/globalValidations/index.ts +++ b/services/ui-src/src/measures/2023/shared/globalValidations/index.ts @@ -14,7 +14,7 @@ export * from "shared/globalValidations/validateDualPopInformation"; export * from "shared/globalValidations/validateEqualCategoryDenominators"; export * from "shared/globalValidations/validateEqualQualifierDenominators"; export * from "shared/globalValidations/validateFfsRadioButtonCompletion"; -export * from "./validateRateNotZero"; +export * from "shared/globalValidations/validateRateNotZero"; export * from "./validateRateZero"; export * from "shared/globalValidations/validateNumeratorsLessThanDenominators"; export * from "shared/globalValidations/validateOneCatRateHigherThanOtherCat"; diff --git a/services/ui-src/src/measures/2023/shared/globalValidations/validateRateNotZero/index.ts b/services/ui-src/src/measures/2023/shared/globalValidations/validateRateNotZero/index.ts deleted file mode 100644 index 0e6d6515b9..0000000000 --- a/services/ui-src/src/measures/2023/shared/globalValidations/validateRateNotZero/index.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { - OmsValidationCallback, - FormRateField, - UnifiedValFuncProps as UVFP, -} from "../types"; -import { - convertOmsDataToRateArray, - getOtherPerformanceMeasureRateArray, -} from "../dataDrivenTools"; -import { LabelData } from "utils"; - -export const validationRateNotZero = ({ - location, - rateData, - errorMessage, -}: UVFP) => { - const errorArray: FormError[] = []; - - for (const ratefields of rateData) { - for (const rate of ratefields) { - if (rate && rate.denominator && rate.numerator && rate.rate) { - if ( - parseFloat(rate.numerator) > 0 && - parseFloat(rate.denominator) > 0 && - parseFloat(rate.rate) === 0 - ) { - errorArray.push({ - errorLocation: location, - errorMessage: - errorMessage ?? - "Rate should not be 0 if numerator and denominator are not 0. If the calculated rate is less than 0.5, disregard this validation.", - }); - } - } - } - } - - return errorArray; -}; - -export const validateRateNotZeroOMS = - (errorMessage?: string): OmsValidationCallback => - ({ categories, qualifiers, rateData, label, locationDictionary }) => { - return validationRateNotZero({ - categories, - qualifiers, - location: `Optional Measure Stratification: ${locationDictionary(label)}`, - rateData: convertOmsDataToRateArray(categories, qualifiers, rateData), - errorMessage, - }).filter((v, i, a) => i === 0 || a[0].errorLocation !== v.errorLocation); - }; - -// If a user manually over-rides a rate it must not violate two rules: -// It must be zero if the numerator is zero -export const validateRateNotZeroPM = ( - performanceMeasureArray: FormRateField[][], - OPM: any, - _qualifiers: LabelData[], - errorMessage?: string -) => { - const errorArray: FormError[] = []; - const location = `Performance Measure/Other Performance Measure`; - const rateDataOPM = getOtherPerformanceMeasureRateArray(OPM); - - const errors = [ - ...validationRateNotZero({ - location, - rateData: performanceMeasureArray, - errorMessage, - }), - ...validationRateNotZero({ - location, - rateData: rateDataOPM, - errorMessage, - }), - ]; - if (!!errors.length) errorArray.push(errors[0]); - return errorArray; -}; diff --git a/services/ui-src/src/measures/2023/shared/util/validationsMock.tsx b/services/ui-src/src/measures/2023/shared/util/validationsMock.tsx index 08af6c0d91..245a8a6e1e 100644 --- a/services/ui-src/src/measures/2023/shared/util/validationsMock.tsx +++ b/services/ui-src/src/measures/2023/shared/util/validationsMock.tsx @@ -9,7 +9,7 @@ import * as validateDualPopInformation from "shared/globalValidations/validateDu import * as validateEqualCategoryDenominators from "shared/globalValidations/validateEqualCategoryDenominators"; import * as validateEqualQualifierDenominators from "shared/globalValidations/validateEqualQualifierDenominators"; import * as validateFfsRadioButtonCompletion from "shared/globalValidations/validateFfsRadioButtonCompletion"; -import * as validateRateNotZero from "measures/2023/shared/globalValidations/validateRateNotZero"; +import * as validateRateNotZero from "shared/globalValidations/validateRateNotZero"; import * as validateRateZero from "measures/2023/shared/globalValidations/validateRateZero"; import * as validateNumeratorsLessThanDenominators from "shared/globalValidations/validateNumeratorsLessThanDenominators"; import * as validateOneCatRateHigherThanOtherCat from "shared/globalValidations/validateOneCatRateHigherThanOtherCat"; diff --git a/services/ui-src/src/measures/2024/shared/globalValidations/index.ts b/services/ui-src/src/measures/2024/shared/globalValidations/index.ts index 8f04e494b3..132098e8ac 100644 --- a/services/ui-src/src/measures/2024/shared/globalValidations/index.ts +++ b/services/ui-src/src/measures/2024/shared/globalValidations/index.ts @@ -15,7 +15,7 @@ export * from "shared/globalValidations/validateDualPopInformation"; export * from "shared/globalValidations/validateEqualCategoryDenominators"; export * from "shared/globalValidations/validateEqualQualifierDenominators"; export * from "shared/globalValidations/validateFfsRadioButtonCompletion"; -export * from "./validateRateNotZero"; +export * from "shared/globalValidations/validateRateNotZero"; export * from "./validateRateZero"; export * from "shared/globalValidations/validateNumeratorsLessThanDenominators"; export * from "shared/globalValidations/validateOneCatRateHigherThanOtherCat"; diff --git a/services/ui-src/src/measures/2024/shared/globalValidations/validateRateNotZero/index.test.ts b/services/ui-src/src/measures/2024/shared/globalValidations/validateRateNotZero/index.test.ts deleted file mode 100644 index 50878bfeef..0000000000 --- a/services/ui-src/src/measures/2024/shared/globalValidations/validateRateNotZero/index.test.ts +++ /dev/null @@ -1,167 +0,0 @@ -import { validateRateNotZeroOMS, validateRateNotZeroPM } from "."; -import { - generateOmsQualifierRateData, - locationDictionary, - manualZeroRate, - manualNonZeroRate, - simpleRate, - partialRate, - generateOtherPerformanceMeasureData, -} from "utils/testUtils/validationHelpers"; - -describe("Testing Non-Zero/No Zero Numerator/Rate Validation", () => { - const categories = [ - { label: "TestCat1", text: "TestCat1", id: "TestCat1" }, - { label: "TestCat2", text: "TestCat2", id: "TestCat2" }, - ]; - const qualifiers = [ - { label: "TestQual1", text: "TestQual1", id: "TestQual1" }, - { label: "TestQual2", text: "TestQual2", id: "TestQual2" }, - ]; - - const baseOMSInfo = { - categories, - qualifiers, - locationDictionary, - isOPM: false, - label: ["TestLabel"], - }; - - // PM - describe("PM/OPM Validation", () => { - it("should return NO errors", () => { - const errors = validateRateNotZeroPM( - [[simpleRate, simpleRate]], - undefined, - qualifiers - ); - - expect(errors).toHaveLength(0); - }); - - it("should have NO error for zero numerator but rate non-zero - Hybrid", () => { - const errors = validateRateNotZeroPM( - [], - generateOtherPerformanceMeasureData([ - manualNonZeroRate, - manualNonZeroRate, - manualNonZeroRate, - ]), - qualifiers - ); - - expect(errors).toHaveLength(0); - }); - - it("should have error for zero rate but numerator non-zero", () => { - const errors = validateRateNotZeroPM( - [ - [manualZeroRate, manualZeroRate], - [manualZeroRate, manualZeroRate], - ], - undefined, - qualifiers - ); - - expect(errors).toHaveLength(1); - expect(errors[0].errorLocation).toBe( - `Performance Measure/Other Performance Measure` - ); - expect(errors[0].errorMessage).toBe( - "Rate should not be 0 if numerator and denominator are not 0. If the calculated rate is less than 0.5, disregard this validation." - ); - }); - - it("should have error for zero rate but numerator non-zero - OPM", () => { - const errors = validateRateNotZeroPM( - [], - generateOtherPerformanceMeasureData([ - manualZeroRate, - manualZeroRate, - manualZeroRate, - ]), - qualifiers - ); - - expect(errors).toHaveLength(1); - expect(errors[0].errorLocation).toBe( - `Performance Measure/Other Performance Measure` - ); - expect(errors[0].errorMessage).toBe( - "Rate should not be 0 if numerator and denominator are not 0. If the calculated rate is less than 0.5, disregard this validation." - ); - }); - - it("should NOT have error from empty rate value", () => { - const errors = validateRateNotZeroPM( - [ - [partialRate, partialRate], - [partialRate, partialRate], - ], - undefined, - qualifiers - ); - - expect(errors).toHaveLength(0); - }); - - it("Error message text should match provided errorMessage", () => { - const errorMessage = "Another one bites the dust."; - const errors = validateRateNotZeroPM( - [ - [manualZeroRate, manualZeroRate], - [manualZeroRate, manualZeroRate], - ], - undefined, - qualifiers, - errorMessage - ); - - expect(errors).toHaveLength(1); - expect(errors[0].errorLocation).toBe( - `Performance Measure/Other Performance Measure` - ); - expect(errors[0].errorMessage).toBe(errorMessage); - }); - }); - - // OMS - describe("OMS Validation", () => { - it("should have error for zero numerator but rate non-zero", () => { - const data = generateOmsQualifierRateData(categories, qualifiers, [ - manualZeroRate, - manualZeroRate, - ]); - const errors = validateRateNotZeroOMS()({ - ...baseOMSInfo, - rateData: data, - }); - - expect(errors).toHaveLength(1); - expect(errors[0].errorLocation).toContain( - "Optional Measure Stratification: TestLabel" - ); - expect(errors[0].errorMessage).toBe( - "Rate should not be 0 if numerator and denominator are not 0. If the calculated rate is less than 0.5, disregard this validation." - ); - }); - }); - - it("Error message text should match provided errorMessage", () => { - const errorMessage = "Another one bites the dust."; - const data = generateOmsQualifierRateData(categories, qualifiers, [ - manualZeroRate, - manualZeroRate, - ]); - const errors = validateRateNotZeroOMS(errorMessage)({ - ...baseOMSInfo, - rateData: data, - }); - - expect(errors).toHaveLength(1); - expect(errors[0].errorLocation).toContain( - "Optional Measure Stratification: TestLabel" - ); - expect(errors[0].errorMessage).toBe(errorMessage); - }); -}); diff --git a/services/ui-src/src/measures/2024/shared/util/validationsMock.tsx b/services/ui-src/src/measures/2024/shared/util/validationsMock.tsx index 25f2d3f615..2621815aac 100644 --- a/services/ui-src/src/measures/2024/shared/util/validationsMock.tsx +++ b/services/ui-src/src/measures/2024/shared/util/validationsMock.tsx @@ -9,7 +9,7 @@ import * as validateDualPopInformation from "shared/globalValidations/validateDu import * as validateEqualCategoryDenominators from "shared/globalValidations/validateEqualCategoryDenominators"; import * as validateEqualQualifierDenominators from "shared/globalValidations/validateEqualQualifierDenominators"; import * as validateFfsRadioButtonCompletion from "shared/globalValidations/validateFfsRadioButtonCompletion"; -import * as validateRateNotZero from "measures/2024/shared/globalValidations/validateRateNotZero"; +import * as validateRateNotZero from "shared/globalValidations/validateRateNotZero"; import * as validateRateZero from "measures/2024/shared/globalValidations/validateRateZero"; import * as validateNumeratorsLessThanDenominators from "shared/globalValidations/validateNumeratorsLessThanDenominators"; import * as validateOneCatRateHigherThanOtherCat from "shared/globalValidations/validateOneCatRateHigherThanOtherCat"; diff --git a/services/ui-src/src/measures/2023/shared/globalValidations/validateRateNotZero/index.test.ts b/services/ui-src/src/shared/globalValidations/validateRateNotZero/index.test.ts similarity index 100% rename from services/ui-src/src/measures/2023/shared/globalValidations/validateRateNotZero/index.test.ts rename to services/ui-src/src/shared/globalValidations/validateRateNotZero/index.test.ts diff --git a/services/ui-src/src/measures/2024/shared/globalValidations/validateRateNotZero/index.ts b/services/ui-src/src/shared/globalValidations/validateRateNotZero/index.ts similarity index 98% rename from services/ui-src/src/measures/2024/shared/globalValidations/validateRateNotZero/index.ts rename to services/ui-src/src/shared/globalValidations/validateRateNotZero/index.ts index 0e6d6515b9..b8c09fc4e7 100644 --- a/services/ui-src/src/measures/2024/shared/globalValidations/validateRateNotZero/index.ts +++ b/services/ui-src/src/shared/globalValidations/validateRateNotZero/index.ts @@ -2,7 +2,7 @@ import { OmsValidationCallback, FormRateField, UnifiedValFuncProps as UVFP, -} from "../types"; +} from "../../types/TypeValidations"; import { convertOmsDataToRateArray, getOtherPerformanceMeasureRateArray,