Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pull previous year value for 3c fields #139761

Merged
merged 3 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 54 additions & 21 deletions services/ui-src/src/components/fields/Integer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,54 @@ import { TextField } from "@cmsgov/design-system";
import { useSelector } from "react-redux";
import { generateQuestionNumber } from "../utils/helperFunctions";

const getPrevYearValue = (question, lastYearFormData) => {
let prevYearValue;

// Split and create array from id
const splitID = question.id.split("-");

// the subquestion id (a, b, c, etc)
const questionId = splitID[5];

// Custom handling for -03-c-05 and -03-c-06
if (
splitID[1] === "03" &&
splitID[2] === "c" &&
(splitID[3] === "05" || splitID[3] === "06") &&
questionId === "a" &&
parseInt(splitID[4]) > 2 &&
parseInt(splitID[4]) < 10
) {
// Set year to last year
splitID[0] = parseInt(splitID[0]) - 1;
splitID.pop();

const fieldsetId = splitID.join("-");
const partIndex = parseInt(splitID[3]) - 1;

// Get questions from last years JSON
const questions =
lastYearFormData[3].contents.section.subsections[2].parts[partIndex]
.questions;

// Filter down to this question
const matchingQuestion = questions.filter(
(question) => fieldsetId === question?.fieldset_info?.id
);

// The first will always be correct
if (matchingQuestion[0]) {
prevYearValue = parseInt(matchingQuestion[0].questions[0].answer?.entry);
}
}
return prevYearValue;
};

const Integer = ({ onChange, question, prevYear, ...props }) => {
const [error, setError] = useState(false);
const [answer, setAnswer] = useState(question.answer.entry);
const lastYearTotals = useSelector((state) => state.lastYearTotals);
const prevYearNumber =
lastYearTotals[question.id.substring(0, question.id.length - 2)];
const lastYearFormData = useSelector((state) => state.lastYearFormData);

const change = ({ target: { name, value } }) => {
const stripped = value.replace(/[^0-9]+/g, "");
const parsed = parseFloat(stripped);
Expand All @@ -25,22 +67,14 @@ const Integer = ({ onChange, question, prevYear, ...props }) => {
}
};

if (prevYearNumber && question.id.indexOf("-a") > -1) {
return (
<TextField
className="ds-c-input"
errorMessage={error}
label={`${generateQuestionNumber(question.id)} ${question.label}`}
hint={question.hint}
name={question.id}
numeric
onChange={change}
value={prevYearNumber}
{...props}
/>
);
}
const renderAnswer = (val) => (val || Number.isInteger(val) ? val : ""); // may attempt to rerender string on page load, so both val || isInteger
const renderAnswer = () => {
if (answer === null) {
return getPrevYearValue(question, lastYearFormData) ?? prevYear?.value;
} else {
// may attempt to rerender string on page load, so both answer || isInteger
return answer || Number.isInteger(answer) ? answer : "";
}
};
return (
<TextField
className="ds-c-input"
Expand All @@ -50,7 +84,7 @@ const Integer = ({ onChange, question, prevYear, ...props }) => {
name={question.id}
numeric
onChange={change}
value={answer != null ? renderAnswer(answer) : prevYear && prevYear.value}
value={renderAnswer()}
{...props}
/>
);
Expand All @@ -61,5 +95,4 @@ Integer.propTypes = {
prevYear: PropTypes.object,
};

export { Integer };
export default Integer;
52 changes: 51 additions & 1 deletion services/ui-src/src/components/fields/Integer.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,40 @@ import Integer from "./Integer";
import { screen, render, fireEvent } from "@testing-library/react";

const mockStore = configureMockStore();
const store = mockStore({ lastYearTotals: { 2022: [] } });
const lastYearFormData = [
{},
{},
{},
{
contents: {
section: {
subsections: [
{},
{},
{
parts: [
{},
{},
{},
{},
{
questions: [
{
fieldset_info: {
id: "2022-03-c-05-03",
},
questions: [{ answer: { entry: 3000 } }],
},
],
},
],
},
],
},
},
},
];
const store = mockStore({ lastYearTotals: { 2022: [] }, lastYearFormData });
const buildInteger = (intProps) => {
return (
<Provider store={store}>
Expand Down Expand Up @@ -73,4 +106,21 @@ describe("<Integer />", () => {
expect(screen.queryByDisplayValue("raw text")).not.toBeInTheDocument();
expect(screen.getByRole("alert")).toBeInTheDocument();
});

it("should render previous year value for appropriate 3c part 5 or 6 questions", () => {
const props = {
question: {
id: "2023-03-c-05-03-a",
label: "How much?",
answer: { entry: null },
},
};

render(buildInteger(props));

expect(screen.getByDisplayValue("3000")).toBeInTheDocument();
const input = screen.getByRole("textbox");
fireEvent.change(input, { target: { value: 234 } });
expect(screen.getByDisplayValue("234")).toBeInTheDocument();
});
});
2 changes: 1 addition & 1 deletion services/ui-src/src/components/fields/Money.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import PropTypes from "prop-types";
import { Integer } from "./Integer";
import Integer from "./Integer";

const Money = ({ ...props }) => {
return <Integer {...props} inputMode="currency" mask="currency" />;
Expand Down
2 changes: 1 addition & 1 deletion services/ui-src/src/components/fields/Question.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { DateRange } from "./DateRange";
import { Email } from "./Email";
import { Fieldset } from "./Fieldset";
import UploadComponent from "../layout/UploadComponent";
import { Integer } from "./Integer";
import Integer from "./Integer";
import { MailingAddress } from "./MailingAddress";
import { Money } from "./Money";
import { Objectives } from "./Objectives";
Expand Down