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

HTML-720 : <workflowState/> should apply only to "current" program enrollment #172

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,12 @@ public void shouldTransitionToStateBeforeAnotherState() throws Exception {
//Given: Patient has a workflow state of X starting in Jan 2012
transitionToState(END_STATE, DATE);

ProgramWorkflowState state = Context.getProgramWorkflowService().getStateByUuid(START_STATE);

List<PatientProgram> patientPrograms = Context.getProgramWorkflowService().getPatientPrograms(patient,
state.getProgramWorkflow().getProgram(), null, null, null, null, false);
patientPrograms.size();

new RegressionTestHelper() {

@Override
Expand Down Expand Up @@ -868,6 +874,214 @@ public void testEditFormHtml(String html) {
}.run();
}

@Test
public void shouldAllowNewProgramAfterCompletedProgram() throws Exception {
//Given: Patient has a workflow state of X starting in Jan 2012
transitionToState(START_STATE, FURTHER_PAST_DATE);
transitionToState(END_STATE, PAST_DATE);

new RegressionTestHelper() {

@Override
public String getFormName() {
return XML_FORM_NAME;
}

@Override
public String[] widgetLabels() {
return new String[] { "Date:", "Location:", "Provider:", "State:" };
}

@Override
public void setupRequest(MockHttpServletRequest request, Map<String, String> widgets) {
request.addParameter(widgets.get("Location:"), "2");
request.addParameter(widgets.get("Provider:"), "502");

//When: Html form is being back entered with an encounter date of June 2011, in which the workflow state selected is Y
request.addParameter(widgets.get("Date:"), dateAsString(DATE));
request.addParameter(widgets.get("State:"), START_STATE);
}

@Override
public void testResults(SubmissionResults results) {
results.assertNoErrors();
results.assertEncounterCreated();
results.assertProvider(502);
results.assertLocation(2);

//Then: Workflow state Y is created with a start date of June 2011 and a stop date of Jan 2012. Workflow state X stays as is.
ProgramWorkflowState state = Context.getProgramWorkflowService().getStateByUuid(START_STATE);
PatientProgram patientProgram = getPatientProgramByState(results.getPatient(), state, DATE);
PatientState patientState = getPatientState(patientProgram, state, DATE);

List<PatientProgram> patientPrograms = Context.getProgramWorkflowService().getPatientPrograms(patient,
state.getProgramWorkflow().getProgram(), null, null, null, null, false);

Assert.assertEquals(2, patientPrograms.size());

Assert.assertNotNull(patientProgram);
Assert.assertEquals(dateAsString(DATE), dateAsString(patientProgram.getDateEnrolled()));
Assert.assertEquals(dateAsString(DATE), dateAsString(patientState.getStartDate()));
Assert.assertNull(patientState.getEndDate());

state = Context.getProgramWorkflowService().getStateByUuid(START_STATE);
patientState = getPatientState(patientProgram, state, DATE);
Assert.assertEquals(dateAsString(DATE), dateAsString(patientState.getStartDate()));
Assert.assertNull(patientState.getEndDate());
}
}.run();

}

@Test
public void shouldAllowNewProgramAfterCompletedProgramViaEdit() throws Exception {
//Given: Patient has a workflow state of X starting in Jan 2012
transitionToState(START_STATE, FURTHER_PAST_DATE);
transitionToState(END_STATE, PAST_DATE);

new RegressionTestHelper() {

@Override
public String getFormName() {
return XML_FORM_NAME;
}

@Override
public String[] widgetLabels() {
return new String[] { "Date:", "Location:", "Provider:", "State:" };
}

@Override
public void setupRequest(MockHttpServletRequest request, Map<String, String> widgets) {
request.addParameter(widgets.get("Location:"), "2");
request.addParameter(widgets.get("Provider:"), "502");

//When: Html form is being back entered with an encounter date of June 2011, in which the workflow state selected is Y
request.addParameter(widgets.get("Date:"), dateAsString(DATE));
}

@Override
public void testResults(SubmissionResults results) {
results.assertNoErrors();
results.assertEncounterCreated();
results.assertProvider(502);
results.assertLocation(2);
}

@Override
public boolean doEditEncounter() {
return true;
}

@Override
public String[] widgetLabelsForEdit() {
return new String[] { "Date:", "Location:", "Provider:", "State:" };
}

@Override
public void setupEditRequest(MockHttpServletRequest request, Map<String, String> widgets) {
request.setParameter(widgets.get("Location:"), "2");
request.setParameter(widgets.get("Provider:"), "502");
request.setParameter(widgets.get("Date:"), dateAsString(DATE));
request.setParameter(widgets.get("State:"), START_STATE);
}

@Override
public void testEditedResults(SubmissionResults results) {
results.assertNoErrors();

ProgramWorkflowState state = Context.getProgramWorkflowService().getStateByUuid(START_STATE);
PatientProgram patientProgram = getPatientProgramByState(results.getPatient(), state, DATE);
PatientState patientState = getPatientState(patientProgram, state, DATE);
Assert.assertNotNull(patientProgram);
Assert.assertEquals(dateAsString(DATE), dateAsString(patientProgram.getDateEnrolled()));
Assert.assertEquals(dateAsString(DATE), dateAsString(patientState.getStartDate()));
Assert.assertNull(patientProgram.getDateCompleted());
Assert.assertNull(patientState.getEndDate());

List<PatientProgram> patientPrograms = Context.getProgramWorkflowService().getPatientPrograms(patient,
patientProgram.getProgram(), null, null, null, null, false);

Assert.assertEquals(2, patientPrograms.size());
}
}.run();

}

@Test
public void shouldAllowNewProgramAfterCompletedProgramViaEditToEarlierDate() throws Exception {
//Given: Patient has a workflow state of X starting in Jan 2012
transitionToState(END_STATE, FURTHER_PAST_DATE);

new RegressionTestHelper() {

@Override
public String getFormName() {
return XML_FORM_NAME;
}

@Override
public String[] widgetLabels() {
return new String[] { "Date:", "Location:", "Provider:", "State:" };
}

@Override
public void setupRequest(MockHttpServletRequest request, Map<String, String> widgets) {
request.addParameter(widgets.get("Location:"), "2");
request.addParameter(widgets.get("Provider:"), "502");

//When: Html form is being back entered with an encounter date of June 2011, in which the workflow state selected is Y
request.addParameter(widgets.get("Date:"), dateAsString(PAST_DATE));
}

@Override
public void testResults(SubmissionResults results) {
results.assertNoErrors();
results.assertEncounterCreated();
results.assertProvider(502);
results.assertLocation(2);
}

@Override
public boolean doEditEncounter() {
return true;
}

@Override
public String[] widgetLabelsForEdit() {
return new String[] { "Date:", "Location:", "Provider:", "State:" };
}

@Override
public void setupEditRequest(MockHttpServletRequest request, Map<String, String> widgets) {
request.setParameter(widgets.get("Location:"), "2");
request.setParameter(widgets.get("Provider:"), "502");
request.setParameter(widgets.get("Date:"), dateAsString(DATE));
request.setParameter(widgets.get("State:"), START_STATE);
}

@Override
public void testEditedResults(SubmissionResults results) {
results.assertNoErrors();

ProgramWorkflowState state = Context.getProgramWorkflowService().getStateByUuid(START_STATE);
PatientProgram patientProgram = getPatientProgramByState(results.getPatient(), state, DATE);
PatientState patientState = getPatientState(patientProgram, state, DATE);
Assert.assertNotNull(patientProgram);
Assert.assertEquals(dateAsString(DATE), dateAsString(patientProgram.getDateEnrolled()));
Assert.assertEquals(dateAsString(DATE), dateAsString(patientState.getStartDate()));
Assert.assertNull(patientProgram.getDateCompleted());
Assert.assertNull(patientState.getEndDate());

List<PatientProgram> patientPrograms = Context.getProgramWorkflowService().getPatientPrograms(patient,
patientProgram.getProgram(), null, null, null, null, false);

Assert.assertEquals(2, patientPrograms.size());
}
}.run();

}

@Test
public void shouldAllowToEditStateWithSameDate() throws Exception {
new RegressionTestHelper() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,21 @@ public void transitionToState(ProgramWorkflowState state) {
throw new IllegalArgumentException("Cannot change state without an Encounter");

// fetch any existing patient program with a state from this workflow
PatientProgram patientProgram = HtmlFormEntryUtil.getPatientProgramByWorkflow(patient, state.getProgramWorkflow());
PatientProgram patientProgram = HtmlFormEntryUtil.getPatientProgramByProgramOnDate(patient,
state.getProgramWorkflow().getProgram(), encounter.getEncounterDatetime());

//if there was none
if (patientProgram == null) {
//fall back to old behavior for lookup
Copy link
Member

Choose a reason for hiding this comment

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

Let's add a reference to ticket HTML-720 for people who want to understand the details.

patientProgram = HtmlFormEntryUtil.getPatientProgramByWorkflow(patient, state.getProgramWorkflow());

//but if this program was already completed, act like there was none
//so a new program enrollment will be created
if (patientProgram != null && patientProgram.getDateCompleted() != null
&& !patientProgram.getDateCompleted().after(encounter.getEncounterDatetime())) {
patientProgram = null;
}
}

// if no existing patient program, see if a patient program for this program is already set to be created at part of this submission (HTML-416)
if (patientProgram == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,23 @@ else if (!(widget instanceof HiddenFieldWidget)){
* @return
*/
private PatientState getActivePatientState(Patient patient, Date encounterDatetime, ProgramWorkflow workflow) {
PatientProgram patientProgram = HtmlFormEntryUtil.getPatientProgramByWorkflow(patient, workflow);
//try getting the state based on the encounter datetime
PatientProgram patientProgram = HtmlFormEntryUtil.getPatientProgramByProgramOnDate(patient, workflow.getProgram(),
encounterDatetime);

//if there was none
if (patientProgram == null) {
//fall back to old behavior for lookup
patientProgram = HtmlFormEntryUtil.getPatientProgramByWorkflow(patient, workflow);

//but if this program was already completed, and this is not a retroactive entry,
//act like there was no program, so a new program enrollment will be created
if (patientProgram != null && patientProgram.getDateCompleted() != null
&& !patientProgram.getDateCompleted().after(encounterDatetime)) {
patientProgram = null;
}
}

if (patientProgram != null) {
for (PatientState patientState : patientProgram.statesInWorkflow(workflow,false)) {
if (patientState.getActive(encounterDatetime)) {
Expand Down Expand Up @@ -215,9 +231,15 @@ public void handleSubmission(FormEntrySession session, HttpServletRequest submis
if (!StringUtils.isBlank(stateUuid)) {
if (Mode.EDIT.equals(session.getContext().getMode())) {

Date prevDate = session.getContext().getPreviousEncounterDate();
if (prevDate == null) {
prevDate = session.getEncounter().getEncounterDatetime();
}

ProgramWorkflowState newState = Context.getProgramWorkflowService().getStateByUuid(stateUuid);
PatientState oldPatientState = getActivePatientState(session.getContext().getExistingPatient(), session
.getContext().getPreviousEncounterDate(), workflow);
//find which state is "currently" active given the "current" encounter time
PatientState oldPatientState = getActivePatientState(session.getContext().getExistingPatient(),
prevDate, workflow);

// if no old state, simply transition to this new state
if (oldPatientState == null) {
Expand Down