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

Implement Need and Program Pages #37

Merged
merged 6 commits into from
Feb 16, 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
52 changes: 40 additions & 12 deletions src/main/java/org/mdbenefits/app/data/enums/HelpNeededType.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,52 @@
import static org.mdbenefits.app.data.enums.ProgramType.SNAP;
import static org.mdbenefits.app.data.enums.ProgramType.TCA;
import static org.mdbenefits.app.data.enums.ProgramType.TDAP;
import static org.mdbenefits.app.data.enums.ProgramType.OTHER;
import static org.mdbenefits.app.data.enums.ProgramType.RCA;

import java.lang.reflect.Array;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;

import lombok.Getter;

@Getter
public enum HelpNeededType {

FOOD( "help-needed.food", SNAP),
CHILDREN("help-needed.children", TCA),
//UTILITIES("help-needed.utilities", OHEP),
DISABILITY("help-needed.disability", TDAP),
NOT_SURE("help-needed.not-sure", OTHER);
FOOD("help-needed.food", SNAP, new ArrayList<>(List.of(SNAP, TCA))),
analoo marked this conversation as resolved.
Show resolved Hide resolved
CHILDREN("help-needed.children", TCA, new ArrayList<>(List.of(SNAP, TCA))),
DISABILITY("help-needed.disability", TDAP, new ArrayList<>(List.of(TDAP))),
REFUGEE("help-needed.refugees", RCA, new ArrayList<>(List.of(RCA))),
NOT_SURE("help-needed.not-sure", null, new ArrayList<>(List.of(RCA, TDAP, SNAP, TCA)));

private final String labelSrc;
private final ProgramType programType;
private final ArrayList<ProgramType> relevantPrograms;

static private final Map<String, ArrayList<ProgramType>> MAP_BY_ENUM_NAME = new HashMap<>();
static private final Map<String, ProgramType> MAP_PROGRAM_BY_ENUM_NAME = new HashMap<>();

static {
analoo marked this conversation as resolved.
Show resolved Hide resolved
for (HelpNeededType type : HelpNeededType.values()) {
MAP_BY_ENUM_NAME.put(type.name(), type.relevantPrograms);
MAP_PROGRAM_BY_ENUM_NAME.put(type.name(), type.programType);
};
}

HelpNeededType(String labelSrc, ProgramType programType, ArrayList<ProgramType> relevantPrograms) {
this.labelSrc = labelSrc;
this.programType = programType;
this.relevantPrograms = relevantPrograms;
}

private final String labelSrc;
private final ProgramType programType;
public static List getRelevantProgramsFromName(String name) {
ArrayList<ProgramType> relevantPrograms = MAP_BY_ENUM_NAME.get(name);
return relevantPrograms;
}
analoo marked this conversation as resolved.
Show resolved Hide resolved

HelpNeededType(String labelSrc, ProgramType programType) {
this.labelSrc = labelSrc;
this.programType = programType;
}
public static String getProgramTypeFromName(String name) {
String programType = MAP_PROGRAM_BY_ENUM_NAME.get(name).toString();
return programType;
}
}
28 changes: 12 additions & 16 deletions src/main/java/org/mdbenefits/app/data/enums/ProgramType.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,18 @@
@Getter
public enum ProgramType {

SNAP("choose-programs.snap", "choose-programs.snap.short-desc", "choose-programs.snap.desc"),
TCA("choose-programs.tca","choose-programs.tca.short-desc","choose-programs.tca.desc"),
// OHEP is here, but will not be displayed as the HelpNeeded option that would
// display this is commented out
// Leaving this in for now in case it's helpful for our future logic to have it
OHEP("choose-programs.ohep", "choose-programs.ohep.short-desc", "choose-programs.ohep.desc"),
TDAP("choose-programs.tdap", "choose-programs.tdap.short-desc", "choose-programs.tdap.desc"),
OTHER("choose-programs.other", "", "choose-programs.other.desc");
SNAP("choose-programs.snap", "choose-programs.snap.short-desc", "choose-programs.snap.desc"),
TCA("choose-programs.tca", "choose-programs.tca.short-desc", "choose-programs.tca.desc"),
TDAP("choose-programs.tdap", "choose-programs.tdap.short-desc", "choose-programs.tdap.desc"),
RCA("choose-programs.rca", "choose-programs.rca.short-desc", "choose-programs.rca.desc");

private final String nameSrc;
private final String shortDescSrc;
private final String descSrc;
private final String nameSrc;
private final String shortDescSrc;
private final String descSrc;

ProgramType(String nameSrc, String shortDescSrc, String descSrc) {
this.nameSrc = nameSrc;
this.shortDescSrc = shortDescSrc;
this.descSrc = descSrc;
}
ProgramType(String nameSrc, String shortDescSrc, String descSrc) {
this.nameSrc = nameSrc;
this.shortDescSrc = shortDescSrc;
this.descSrc = descSrc;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.mdbenefits.app.preparers;

import formflow.library.data.Submission;
import formflow.library.pdf.PdfMap;
import formflow.library.pdf.SingleField;
import formflow.library.pdf.SubmissionField;
import formflow.library.pdf.SubmissionFieldPreparer;
import java.util.List;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Component
public class ApplicantNeedsPreparer implements SubmissionFieldPreparer {
@Override
public Map<String, SubmissionField> prepareSubmissionFields(Submission submission, PdfMap pdfMap) {
Map<String, SubmissionField> results = new HashMap<>();

Map<String, Object> inputData = submission.getInputData();

List<String> programs = (List) inputData.get("programs[]");

if (programs.isEmpty()) {
return results;
}

results.put("needsSNAP",
new SingleField("needsSNAP", String.valueOf(programs.contains("SNAP")), null));

boolean needsCash = programs.contains("TDAP") || programs.contains("TCA") || programs.contains("RCA");

results.put("needsCashAssistance",
new SingleField("needsCashAssistance", String.valueOf(needsCash), null));

return results;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.mdbenefits.app.submission.actions;

import formflow.library.config.submission.Action;
import formflow.library.data.Submission;

import java.util.ArrayList;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.mdbenefits.app.data.enums.HelpNeededType;
import org.springframework.stereotype.Component;

/**
* This method stores the program associated with the help needed so that the field appears checked on the choose programs page.
*/
analoo marked this conversation as resolved.
Show resolved Hide resolved
@Component
@Slf4j
public class PreCheckPrograms implements Action {
@Override
public void run(Submission submission) {
List<String> helpNeeded = (List<String>) submission.getInputData().get("helpNeeded[]");
List<String> programsToAdd = new ArrayList<>();

helpNeeded.forEach((String need) -> {
bseeger marked this conversation as resolved.
Show resolved Hide resolved
if (need.equals(HelpNeededType.NOT_SURE.name())) {
submission.getInputData().remove("programs[]");
} else {
programsToAdd.add(HelpNeededType.getProgramTypeFromName(need));
}
});

submission.getInputData().put("programs[]", programsToAdd);
}
}
22 changes: 22 additions & 0 deletions src/main/java/org/mdbenefits/app/utils/ApplicationUtilities.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.mdbenefits.app.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.mdbenefits.app.data.enums.HelpNeededType;

public class ApplicationUtilities {

public static Set<String> flattenHouseholdNeedsPrograms(ArrayList<String> needTypes) {
List<List<String>> relevantPrograms = new ArrayList<>();

needTypes.forEach((String programType) -> {
relevantPrograms.add(HelpNeededType.getRelevantProgramsFromName(programType));
});

return relevantPrograms.stream()
.flatMap(List::stream)
.collect(Collectors.toSet());
}
}
1 change: 1 addition & 0 deletions src/main/resources/flows-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ flow:
nextScreens:
- name: redirectToMDThink
selectHelpNeeded:
beforeSaveAction: PreCheckPrograms
analoo marked this conversation as resolved.
Show resolved Hide resolved
nextScreens:
- name: choosePrograms
choosePrograms:
Expand Down
4 changes: 4 additions & 0 deletions src/main/resources/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ help-needed.food=Help with food
help-needed.children=Help with money for children
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It won't let me mark the right spot, so I'll put this here. If this PR includes the help needed page, then the message for help-needed.subheader needs to be updated as it no longer matches the design.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for the "Help with children" - but I wonder if your message is more up to date based on conversations?

help-needed.utilities=Help with utilities
help-needed.disability=Help for a disability
help-needed.refugees=Help for refugees
help-needed.not-sure=I'm not sure
# MD Think redirect
redirect.mdthink.title=myMDTHINK Redirect
Expand All @@ -266,6 +267,9 @@ choose-programs.ohep.desc=<br>Helps with heating, electric and gas bills. Maryla
choose-programs.tdap=Temporary Disability Assistance Program (TDAP)
choose-programs.tdap.short-desc=Get help for a disability
choose-programs.tdap.desc=<br>Gives cash to people who are low-income and living with short-term disability or who are waiting for federal disability help. People with children who are dependents cannot get this benefit.
choose-programs.rca=Refugee Transitional Cash Assistance (RTCA or RCA)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that it looks like the copy for SNAP and TCA has changed in the designs.

The TDAP needs a line break in on spot to match design.

choose-programs.rca.short-desc=Get help for refugees
choose-programs.rca.desc=<br>Gives cash to people who are refugees until they get jobs and are able to be financially independent.
choose-programs.other=I want to add another program not shown here
choose-programs.other.desc=<br>If you believe there are other benefits you can get or a caseworker at an office believes you can get benefits from another program, choose this option.
# Expedited SNAP
Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/pdf-map.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ inputFields:
isApplicantApplying: isApplicantApplying
citizenshipStatus: isApplicantCitizen
someoneInHHIsPregnant: someoneInHHIsPregnant

needsCashAssistance: applicant_needs_cash_assistance
needsSNAP: applicant_needs_snap
someoneHasDrugKingpinFelony: someoneHasDrugKingpinFelony
someoneHasVolumeDrugDealerFelony: someoneHasVolumeDrugDealerFelony
someoneHasSexualOffenceConviction: someoneHasSexualOffenceConviction
Expand Down
Binary file modified src/main/resources/pdfs/Combined_9701_OHEP.pdf
Binary file not shown.
23 changes: 15 additions & 8 deletions src/main/resources/templates/mdBenefitsFlow/choosePrograms.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,29 @@
th:replace="~{fragments/form :: form(action=${formAction}, content=~{::formContent})}">
<th:block th:ref="formContent">
<div class="form-card__content">
<h2 th:text="#{choose-programs.check-all-that-apply}"></h2>
<th:block th:replace="~{fragments/inputs/checkboxFieldset ::
checkboxFieldset(inputName='programs',
label=#{choose-programs.check-all-that-apply},
ariaLabel=#{choose-programs.header},
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bseeger - do we have a best practice around what to include in the ariaLabel?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, I was wondering that as well. Might be worth checking in with Devon about this.

Copy link
Collaborator

@spokenbird spokenbird Feb 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be the HTML ID of the HTML element you want to label the input. It's meant for screens where there is only one input, and the screens H1 header is technically the label for that input. In most cases the value you want here will be 'header' since that's the ID assigned to headers in the FFB. You can just use the string 'header' in this case, but it shouldn't be a message property.

content=~{::content})}">
<th:block th:ref="content">
<th:block th:each="programType : ${T(org.mdbenefits.app.data.enums.ProgramType).values()}">
<th:block th:if="${fieldData.get('helpNeeded[]').contains(programType.name())}">
<span th:with="shortDesc=${programType.getShortDescSrc().isBlank()} ? '' : #{${programType.getShortDescSrc()}}"
th:utext="${'<b>' + shortDesc + '</b>'}">
</span>
<th:block
th:with="relevantPrograms = ${T(org.mdbenefits.app.utils.ApplicationUtilities).flattenHouseholdNeedsPrograms(fieldData.get('helpNeeded[]'))}">
<th:block
th:each="programType : ${T(org.mdbenefits.app.data.enums.ProgramType).values()}">
<th:block
th:replace="~{fragments/inputs/checkboxInSet:: checkboxInSet(
th:if="${relevantPrograms.contains(programType)}">
<h2
th:with="shortDesc=${programType.getShortDescSrc().isBlank()} ? '' : #{${programType.getShortDescSrc()}}"
th:utext="${shortDesc}">
</h2>
<th:block
th:replace="~{fragments/inputs/checkboxInSet:: checkboxInSet(
analoo marked this conversation as resolved.
Show resolved Hide resolved
inputName='programs',
value=${programType.name()},
label=#{${programType.getNameSrc()}},
checkboxHelpText=#{${programType.getDescSrc()}})}">
</th:block>
</th:block>
</th:block>
</th:block>
Expand All @@ -48,4 +55,4 @@
</div>
<th:block th:replace="~{fragments/footer :: footer}"/>
</body>
</html>
</html>
74 changes: 39 additions & 35 deletions src/main/resources/templates/mdBenefitsFlow/selectHelpNeeded.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,47 @@
<head th:replace="~{fragments/head :: head(title=#{help-needed.title})}"></head>
<body>
<div class="page-wrapper">
<div th:replace="~{fragments/toolbar :: toolbar}"></div>
<section class="slab">
<div class="grid">
<div th:replace="~{fragments/goBack :: goBackLink}"></div>
<main id="content" role="main" class="form-card spacing-above-35">
<th:block th:replace="~{fragments/icons :: choosePrograms}"></th:block>
<th:block
th:replace="~{fragments/cardHeader :: cardHeader(header=#{help-needed.header}, subtext=#{help-needed.subheader})}"/>
<th:block
th:replace="~{fragments/form :: form(action=${formAction}, content=~{::formContent})}">
<th:block th:ref="formContent">
<div class="form-card__content">
<th:block th:replace="~{fragments/inputs/checkboxFieldset ::
checkboxFieldset(inputName='helpNeeded',
label=#{general.check-all-that-apply},
content=~{::content})}">
<th:block th:ref="content">
<th:block th:each="helpNeededType : ${T(org.mdbenefits.app.data.enums.HelpNeededType).values()}">
<th:block
th:replace="~{fragments/inputs/checkboxInSet :: checkboxInSet(
inputName='helpNeeded',
value=${helpNeededType.getProgramType()},
label=#{${helpNeededType.getLabelSrc()}})}">
<div th:replace="~{fragments/toolbar :: toolbar}"></div>
<section class="slab">
<div class="grid">
<div th:replace="~{fragments/goBack :: goBackLink}"></div>
<main id="content" role="main" class="form-card spacing-above-35">
<th:block th:replace="~{fragments/icons :: choosePrograms}"></th:block>
<th:block
th:replace="~{fragments/cardHeader :: cardHeader(header=#{help-needed.header}, subtext=#{help-needed.subheader})}"/>
<th:block
th:replace="~{fragments/form :: form(action=${formAction}, content=~{::formContent})}">
<th:block th:ref="formContent">
<div class="form-card__content">
<th:block th:replace="~{fragments/inputs/checkboxFieldset :: checkboxFieldset(
inputName='helpNeeded',
label=#{general.check-all-that-apply},
content=~{::content})}">
<th:block th:ref="content">
<th:block
th:each="helpNeededType : ${T(org.mdbenefits.app.data.enums.HelpNeededType).values()}">
<th:block
th:with="isOther=${helpNeededType.name().equals(T(org.mdbenefits.app.data.enums.HelpNeededType).NOT_SURE.name())}">
<th:block th:replace="~{fragments/inputs/checkboxInSet :: checkboxInSet(
inputName='helpNeeded',
value=${helpNeededType.name()},
noneOfTheAbove=${isOther},
label=#{${helpNeededType.getLabelSrc()}})}">
</th:block>
</th:block>
</th:block>
</th:block>
</th:block>
</div>
<div class="form-card__footer">
<th:block th:replace="~{fragments/inputs/submitButton :: submitButton(
text=#{general.inputs.continue})}"/>
</div>
</th:block>
</th:block>
</th:block>
</th:block>
</div>
<div class="form-card__footer">
<th:block th:replace="~{fragments/inputs/submitButton :: submitButton(
text=#{general.inputs.continue})}"/>
</div>
</th:block>
</th:block>
</main>
</div>
</section>
</main>
</div>
</section>
</div>
<th:block th:replace="~{fragments/footer :: footer}"/>
</body>
Expand Down
Loading
Loading