Skip to content

Commit 7e5133e

Browse files
committed
html-715
1 parent 705c939 commit 7e5133e

6 files changed

Lines changed: 443 additions & 0 deletions

File tree

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
package org.openmrs.module.htmlformentry;
2+
3+
import java.util.ArrayList;
4+
import java.util.Date;
5+
import java.util.HashSet;
6+
import java.util.List;
7+
import java.util.ListIterator;
8+
import java.util.Map;
9+
import java.util.Set;
10+
import java.util.Stack;
11+
import java.util.Vector;
12+
13+
import javax.servlet.http.HttpServletRequest;
14+
15+
import org.apache.commons.lang.ObjectUtils;
16+
import org.apache.commons.lang.StringUtils;
17+
import org.openmrs.Encounter;
18+
import org.openmrs.Patient;
19+
import org.openmrs.PatientProgram;
20+
import org.openmrs.PatientProgramAttribute;
21+
import org.openmrs.PatientState;
22+
import org.openmrs.Program;
23+
import org.openmrs.ProgramWorkflowState;
24+
import org.openmrs.module.htmlformentry.FormEntryContext.Mode;
25+
import org.openmrs.module.htmlformentry.element.EnrollInProgramElement;
26+
import org.openmrs.module.htmlformentry.widget.CheckboxWidget;
27+
import org.openmrs.module.htmlformentry.widget.DateWidget;
28+
import org.openmrs.module.htmlformentry.widget.ErrorWidget;
29+
import org.openmrs.util.OpenmrsUtil;
30+
31+
public class EnrollInProgramElement2_2 extends EnrollInProgramElement{
32+
33+
private List<PatientProgramAttribute> patientProgramAttributes;
34+
35+
private List<ProgramWorkflowState> states;
36+
37+
private Program program;
38+
39+
private CheckboxWidget checkToEnrollWidget;
40+
41+
private ErrorWidget checkToEnrollErrorWidget;
42+
43+
private DateWidget dateWidget;
44+
45+
private ErrorWidget dateErrorWidget;
46+
47+
private Stack<Object> stack = new Stack<Object>();
48+
49+
private List<PatientProgram> patientProgramsToUpdate = new Vector<PatientProgram>();
50+
51+
private List<PatientProgram> patientProgramsToCreate = new Vector<PatientProgram>();
52+
53+
public EnrollInProgramElement2_2(FormEntryContext context, Map<String, String> parameters) {
54+
super(context, parameters);
55+
56+
57+
try {
58+
program = HtmlFormEntryUtil.getProgram(parameters.get("programId"));
59+
if (program == null)
60+
throw new FormEntryException("");
61+
} catch (Exception ex) {
62+
throw new IllegalArgumentException("Couldn't find program in: " + parameters);
63+
}
64+
65+
if ("true".equalsIgnoreCase(parameters.get("showDate"))) {
66+
dateWidget = new DateWidget();
67+
dateErrorWidget = new ErrorWidget();
68+
context.registerWidget(dateWidget);
69+
context.registerErrorWidget(dateWidget, dateErrorWidget);
70+
}
71+
72+
if ("true".equalsIgnoreCase(parameters.get("showCheckbox"))) {
73+
checkToEnrollWidget = new CheckboxWidget();
74+
{ // If patient is already enrolled, check and disable the checkbox
75+
Patient patient = context.getExistingPatient();
76+
Date encounterDate = (Date) ObjectUtils.defaultIfNull(context.getPreviousEncounterDate(),
77+
ObjectUtils.defaultIfNull(context.getDefaultEncounterDate(), new Date()));
78+
if (HtmlFormEntryUtil.isEnrolledInProgramOnDate(patient, program, encounterDate)) {
79+
checkToEnrollWidget.setInitialValue("true");
80+
checkToEnrollWidget.setDisabled(true);
81+
}
82+
}
83+
context.registerWidget(checkToEnrollWidget);
84+
checkToEnrollErrorWidget = new ErrorWidget();
85+
context.registerErrorWidget(checkToEnrollWidget, checkToEnrollErrorWidget);
86+
}
87+
88+
String patientProgramAttributeIds = parameters.get("patientProgramAttributes");
89+
if (StringUtils.isNotBlank(patientProgramAttributeIds)) {
90+
patientProgramAttributes = new ArrayList<PatientProgramAttribute>();
91+
String[] patientProgramAttributesIdsUuidsOrNames = patientProgramAttributeIds.split(",");
92+
new HashSet<String>();
93+
94+
for (String value : patientProgramAttributesIdsUuidsOrNames) {
95+
value = value.trim();
96+
PatientProgramAttribute programAttribute = HtmlFormEntryUtil2_2.getPatientProgramAttribute(value,
97+
program);
98+
if (programAttribute == null) {
99+
String errorMsgPart = "with an id or uuid";
100+
if (value.indexOf(":") > -1)
101+
throw new FormEntryException(
102+
"Cannot find a program attribute " + errorMsgPart + " that matches '" + value + "'");
103+
}
104+
105+
if (!patientProgramAttributes.contains(programAttribute))
106+
patientProgramAttributes.add(programAttribute);
107+
}
108+
}
109+
110+
String stateIdsStr = parameters.get("stateIds");
111+
if (StringUtils.isNotBlank(stateIdsStr)) {
112+
states = new ArrayList<ProgramWorkflowState>();
113+
String[] stateIdsUuidsOrPrefNames = stateIdsStr.split(",");
114+
// set to store unique work flow state combinations so as to determine multiple
115+
// states in same work flow
116+
Set<String> workflowsAndStates = new HashSet<String>();
117+
for (String value : stateIdsUuidsOrPrefNames) {
118+
value = value.trim();
119+
ProgramWorkflowState state = HtmlFormEntryUtil.getState(value, program);
120+
if (state == null) {
121+
String errorMsgPart = "with an id or uuid";
122+
if (value.indexOf(":") > -1)
123+
errorMsgPart = "associated to a concept with a concept mapping";
124+
throw new FormEntryException(
125+
"Cannot find a program work flow state " + errorMsgPart + " that matches '" + value + "'");
126+
} else if (!state.getInitial()) {
127+
throw new FormEntryException(
128+
"The program work flow state that matches '" + value + "' is not marked as initial");
129+
} else if (!workflowsAndStates.add(state.getProgramWorkflow().getUuid())) {
130+
throw new FormEntryException("A patient cannot be in multiple states in the same workflow");
131+
}
132+
if (!states.contains(state))
133+
states.add(state);
134+
}
135+
136+
137+
}
138+
}
139+
140+
141+
/**
142+
* @see org.openmrs.module.htmlformentry.action.FormSubmissionControllerAction#handleSubmission(org.openmrs.module.htmlformentry.FormEntrySession,
143+
* javax.servlet.http.HttpServletRequest)
144+
*/
145+
@Override
146+
public void handleSubmission(FormEntrySession session, HttpServletRequest submission) {
147+
// Only enroll if we are not in view mode and either the checkbox is checked or
148+
// it doesn't exist
149+
if (session.getContext().getMode() != Mode.VIEW && (checkToEnrollWidget == null
150+
|| "true".equals(checkToEnrollWidget.getValue(session.getContext(), submission)))) {
151+
Date selectedDate = null;
152+
if (dateWidget != null) {
153+
selectedDate = dateWidget.getValue(session.getContext(), submission);
154+
}
155+
enrollInProgram(program, selectedDate, states, patientProgramAttributes);
156+
}
157+
}
158+
159+
private void enrollInProgram(Program program, Date enrollmentDate, List<ProgramWorkflowState> states,
160+
List<PatientProgramAttribute> patientProgramAttributes) {
161+
if (program == null)
162+
throw new IllegalArgumentException("Cannot enroll in a blank program");
163+
164+
Patient patient = highestOnStack(Patient.class);
165+
if (patient == null)
166+
throw new IllegalArgumentException("Cannot enroll in a program outside of a Patient");
167+
Encounter encounter = highestOnStack(Encounter.class);
168+
169+
// if an enrollment date has not been specified, enrollment date is the
170+
// encounter date
171+
enrollmentDate = (enrollmentDate != null) ? enrollmentDate
172+
: (encounter != null) ? encounter.getEncounterDatetime() : null;
173+
174+
if (enrollmentDate == null)
175+
throw new IllegalArgumentException(
176+
"Cannot enroll in a program without specifying an Encounter Date or Enrollment Date");
177+
178+
// only need to do some if the patient is not enrolled in the specified program
179+
// on the specified date
180+
if (!HtmlFormEntryUtil.isEnrolledInProgramOnDate(patient, program, enrollmentDate)) {
181+
182+
// see if the patient is enrolled in this program in the future
183+
PatientProgram pp = HtmlFormEntryUtil.getClosestFutureProgramEnrollment(patient, program, enrollmentDate);
184+
185+
if (pp != null) {
186+
// set the start dates of all states with a start date equal to the enrollment
187+
// date to the selected date
188+
for (PatientState patientState : pp.getStates()) {
189+
if (OpenmrsUtil.nullSafeEquals(patientState.getStartDate(), pp.getDateEnrolled())) {
190+
patientState.setStartDate(enrollmentDate);
191+
}
192+
}
193+
194+
// set the program enrollment date to the newly selected date
195+
pp.setDateEnrolled(enrollmentDate);
196+
197+
patientProgramsToUpdate.add(pp);
198+
}
199+
// otherwise, create the new program
200+
else {
201+
pp = new PatientProgram();
202+
pp.setPatient(patient);
203+
pp.setProgram(program);
204+
if (enrollmentDate != null)
205+
pp.setDateEnrolled(enrollmentDate);
206+
207+
if (states != null) {
208+
for (ProgramWorkflowState programWorkflowState : states) {
209+
pp.transitionToState(programWorkflowState, enrollmentDate);
210+
}
211+
}
212+
213+
if (patientProgramAttributes != null) {
214+
for (PatientProgramAttribute pogramattribute : patientProgramAttributes) {
215+
pp.setAttribute(pogramattribute);
216+
}
217+
}
218+
219+
patientProgramsToCreate.add(pp);
220+
}
221+
222+
}
223+
}
224+
225+
/**
226+
* Utility method that returns the object of a specified class that was most
227+
* recently added to the stack
228+
*/
229+
@SuppressWarnings("unchecked")
230+
private <T> T highestOnStack(Class<T> clazz) {
231+
for (ListIterator<Object> iter = stack.listIterator(stack.size()); iter.hasPrevious();) {
232+
Object o = iter.previous();
233+
if (clazz.isAssignableFrom(o.getClass()))
234+
return (T) o;
235+
}
236+
return null;
237+
}
238+
239+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package org.openmrs.module.htmlformentry;
2+
3+
import org.apache.commons.logging.Log;
4+
import org.apache.commons.logging.LogFactory;
5+
import org.openmrs.PatientProgramAttribute;
6+
import org.openmrs.Program;
7+
import org.openmrs.api.context.Context;
8+
9+
10+
11+
public class HtmlFormEntryUtil2_2 extends HtmlFormEntryUtil{
12+
public static Log log = LogFactory.getLog(HtmlFormEntryUtil2_2.class);
13+
14+
public static PatientProgramAttribute getProgramAttribute(String identifier) {
15+
PatientProgramAttribute pa = null;
16+
if (identifier != null) {
17+
try {
18+
identifier = identifier.trim();
19+
20+
Integer.valueOf(identifier);
21+
pa = getProgramAttribute(identifier);
22+
23+
if (pa != null) {
24+
return pa;
25+
}
26+
} catch (NumberFormatException e) {
27+
}
28+
29+
if (isValidUuidFormat(identifier)) {
30+
pa = Context.getProgramWorkflowService().getPatientProgramAttributeByUuid(identifier);
31+
32+
if (pa != null) {
33+
return pa;
34+
}
35+
}
36+
}
37+
return null;
38+
39+
}
40+
41+
/**
42+
* Looks up a {@link PatientProgramAttribute} from the specified program by
43+
* patientprogramId,uuid
44+
*
45+
* @param identifier the programWorkflowStateId, uuid or the concept name to
46+
* match against
47+
* @param program
48+
* @return <strong>Should</strong> return the patient program attribute with the
49+
* matching id <strong>Should</strong> return the state with the
50+
* matching uuid <strong>Should</strong>
51+
*/
52+
public static PatientProgramAttribute getPatientProgramAttribute(String identifier, Program program) {
53+
54+
if (identifier == null) {
55+
return null;
56+
}
57+
58+
// try to fetch by id or uuid
59+
PatientProgramAttribute progrmAttribute = getProgramAttribute(identifier);
60+
61+
if (progrmAttribute != null) {
62+
return progrmAttribute;
63+
}
64+
return null;
65+
}
66+
67+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.openmrs.module.htmlformentry.handler;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collections;
5+
import java.util.List;
6+
import java.util.Map;
7+
8+
import org.openmrs.Program;
9+
import org.openmrs.ProgramWorkflowState;
10+
import org.openmrs.annotation.OpenmrsProfile;
11+
import org.openmrs.module.htmlformentry.EnrollInProgramElement2_2;
12+
import org.openmrs.module.htmlformentry.FormEntrySession;
13+
import org.openmrs.module.htmlformentry.FormSubmissionController;
14+
15+
@OpenmrsProfile(openmrsPlatformVersion = "2.2.*")
16+
public class EnrollInProgramHandler2_2 extends EnrollInProgramHandler {
17+
18+
@Override
19+
protected List<AttributeDescriptor> createAttributeDescriptors() {
20+
List<AttributeDescriptor> attributeDescriptors = new ArrayList<AttributeDescriptor>();
21+
attributeDescriptors.add(new AttributeDescriptor("programId", Program.class));
22+
attributeDescriptors.add(new AttributeDescriptor("stateIds", ProgramWorkflowState.class));
23+
attributeDescriptors.add(new AttributeDescriptor("patientProgramAttributes", ProgramWorkflowState.class));
24+
return Collections.unmodifiableList(attributeDescriptors);
25+
}
26+
27+
@Override
28+
protected String getSubstitution(FormEntrySession session, FormSubmissionController controllerActions,
29+
Map<String, String> parameters) {
30+
EnrollInProgramElement2_2 element = new EnrollInProgramElement2_2(session.getContext(), parameters);
31+
session.getSubmissionController().addAction(element);
32+
33+
return element.generateHtml(session.getContext());
34+
}
35+
36+
}

0 commit comments

Comments
 (0)