use of org.openmrs.PatientProgram in project openmrs-core by openmrs.
the class ProgramWorkflowServiceTest method purgeProgram_shouldPurgeProgramWithPatientsEnrolled.
@Test
public void purgeProgram_shouldPurgeProgramWithPatientsEnrolled() {
Program program = Context.getProgramWorkflowService().getProgram(2);
// program has at least one patient enrolled
List<PatientProgram> patientPrograms = Context.getProgramWorkflowService().getPatientPrograms(null, program, null, null, null, null, true);
assertTrue(patientPrograms.size() > 0);
Context.getProgramWorkflowService().purgeProgram(program);
// should cascade to patient programs
for (PatientProgram patientProgram : patientPrograms) {
assertNull(Context.getProgramWorkflowService().getPatientProgram(patientProgram.getId()));
}
// make sure that the program was deleted properly
assertNull(Context.getProgramWorkflowService().getProgram(2));
}
use of org.openmrs.PatientProgram in project openmrs-core by openmrs.
the class MigrationHelper method importProgramsAndStatuses.
public static int importProgramsAndStatuses(List<String> programWorkflow) throws ParseException {
ProgramWorkflowService pws = Context.getProgramWorkflowService();
PatientService ps = Context.getPatientService();
List<PatientProgram> patientPrograms = new ArrayList<>();
Map<String, PatientProgram> knownPatientPrograms = new HashMap<>();
Map<String, Program> programsByName = new HashMap<>();
for (Program program : pws.getAllPrograms()) {
programsByName.put(program.getConcept().getName(Context.getLocale(), false).getName(), program);
}
for (String s : programWorkflow) {
// ENROLLMENT:HIVEMR-V1,9266,IMB HIV PROGRAM,2005-08-25,
log.debug(s);
if (s.startsWith("ENROLLMENT:")) {
s = s.substring(s.indexOf(":") + 1);
String[] temp = s.split(",");
PatientIdentifierType pit = ps.getPatientIdentifierTypeByName(temp[0]);
String identifier = temp[1];
List<PatientIdentifier> pis = ps.getPatientIdentifiers(identifier, Collections.singletonList(pit), null, null, null);
if (pis.size() != 1) {
throw new IllegalArgumentException("Found " + pis.size() + " instances of identifier " + identifier + " of type " + pit);
}
Patient p = pis.get(0).getPatient();
Program program = programsByName.get(temp[2]);
if (program == null) {
throw new RuntimeException("Couldn't find program \"" + temp[2] + "\" in " + programsByName);
}
Date enrollmentDate = temp.length < 4 ? null : parseDate(temp[3]);
Date completionDate = temp.length < 5 ? null : parseDate(temp[4]);
PatientProgram pp = new PatientProgram();
pp.setPatient(p);
pp.setProgram(program);
pp.setDateEnrolled(enrollmentDate);
pp.setDateCompleted(completionDate);
patientPrograms.add(pp);
// "HIVEMR-V1,9266,IMB HIV PROGRAM"
knownPatientPrograms.put(temp[0] + "," + temp[1] + "," + temp[2], pp);
} else if (s.startsWith("STATUS:")) {
// STATUS:HIVEMR-V1,9266,IMB HIV PROGRAM,TREATMENT STATUS,ACTIVE,2005-08-25,,
s = s.substring(s.indexOf(":") + 1);
String[] temp = s.split(",");
Program program = programsByName.get(temp[2]);
if (program == null) {
throw new RuntimeException("Couldn't find program \"" + temp[2] + "\" in " + programsByName);
}
ProgramWorkflow wf = program.getWorkflowByName(temp[3]);
if (wf == null) {
throw new RuntimeException("Couldn't find workflow \"" + temp[3] + "\" for program " + program + " (in " + program.getAllWorkflows() + ")");
}
ProgramWorkflowState st = wf.getStateByName(temp[4]);
if (st == null) {
throw new RuntimeException("Couldn't find state \"" + temp[4] + "\" for workflow " + wf + " (in " + wf.getStates() + ")");
}
Date startDate = temp.length < 6 ? null : parseDate(temp[5]);
Date endDate = temp.length < 7 ? null : parseDate(temp[6]);
PatientState state = new PatientState();
PatientProgram pp = knownPatientPrograms.get(temp[0] + "," + temp[1] + "," + temp[2]);
state.setPatientProgram(pp);
state.setState(st);
state.setStartDate(startDate);
state.setEndDate(endDate);
pp.getStates().add(state);
}
}
int numAdded = 0;
for (PatientProgram pp : knownPatientPrograms.values()) {
pws.savePatientProgram(pp);
++numAdded;
}
return numAdded;
}
use of org.openmrs.PatientProgram in project openmrs-core by openmrs.
the class PatientProgramValidator method validate.
/**
* Validates the given PatientProgram.
*
* @param obj The patient program to validate.
* @param errors Errors
* @see org.springframework.validation.Validator#validate(java.lang.Object,
* org.springframework.validation.Errors)
* @should fail validation if obj is null
* @should fail if the patient field is blank
* @should fail if there is more than one patientState with the same states and startDates
* @should fail if there is more than one state with a null start date in the same workflow
* @should pass if the start date of the first patient state in the work flow is null
* @should fail if any patient state has an end date before its start date
* @should fail if the program property is null
* @should fail if any patient states overlap each other in the same work flow
* @should fail if a patientState has an invalid work flow state
* @should fail if a patient program has duplicate states in the same work flow
* @should fail if a patient is in multiple states in the same work flow
* @should fail if a enrolled date is in future at the date it set
* @should fail if a completion date is in future at the date it set
* @should fail if a patient program has an enroll date after its completion
* @should pass if a patient is in multiple states in different work flows
* @should pass for a valid program
* @should pass for patient states that have the same start dates in the same work flow
* @should pass validation if field lengths are correct
* @should fail validation if field lengths are not correct
*/
@Override
public void validate(Object obj, Errors errors) {
if (log.isDebugEnabled()) {
log.debug(this.getClass().getName() + ".validate...");
}
if (obj == null) {
throw new IllegalArgumentException("The parameter obj should not be null");
}
MessageSourceService mss = Context.getMessageSourceService();
PatientProgram patientProgram = (PatientProgram) obj;
ValidationUtils.rejectIfEmpty(errors, "patient", "error.required", new Object[] { mss.getMessage("general.patient") });
ValidationUtils.rejectIfEmpty(errors, "program", "error.required", new Object[] { mss.getMessage("Program.program") });
if (errors.hasErrors()) {
return;
}
ValidationUtils.rejectIfEmpty(errors, "dateEnrolled", "error.patientProgram.enrolledDateEmpty");
Date today = new Date();
if (patientProgram.getDateEnrolled() != null && today.before(patientProgram.getDateEnrolled())) {
errors.rejectValue("dateEnrolled", "error.patientProgram.enrolledDateDateCannotBeInFuture");
}
if (patientProgram.getDateCompleted() != null && today.before(patientProgram.getDateCompleted())) {
errors.rejectValue("dateCompleted", "error.patientProgram.completionDateCannotBeInFuture");
}
// if enrollment or complete date of program is in future or complete date has come before enroll date we should throw error
if (patientProgram.getDateEnrolled() != null && OpenmrsUtil.compareWithNullAsLatest(patientProgram.getDateCompleted(), patientProgram.getDateEnrolled()) < 0) {
errors.rejectValue("dateCompleted", "error.patientProgram.enrolledDateShouldBeBeforecompletionDate");
}
Set<ProgramWorkflow> workFlows = patientProgram.getProgram().getWorkflows();
// Patient state validation is specific to a work flow
for (ProgramWorkflow workFlow : workFlows) {
Set<PatientState> patientStates = patientProgram.getStates();
if (patientStates != null) {
// Set to store to keep track of unique valid state and start date combinations
Set<String> statesAndStartDates = new HashSet<>();
PatientState latestState = null;
boolean foundCurrentPatientState = false;
boolean foundStateWithNullStartDate = false;
for (PatientState patientState : patientStates) {
if (patientState.getVoided()) {
continue;
}
String missingRequiredFieldCode = null;
// only the initial state can have a null start date
if (patientState.getStartDate() == null) {
if (foundStateWithNullStartDate) {
missingRequiredFieldCode = "general.dateStart";
} else {
foundStateWithNullStartDate = true;
}
} else if (patientState.getState() == null) {
missingRequiredFieldCode = "State.state";
}
if (missingRequiredFieldCode != null) {
errors.rejectValue("states", "PatientState.error.requiredField", new Object[] { mss.getMessage(missingRequiredFieldCode) }, null);
return;
}
// state should belong to one of the workflows in the program
// note that we are iterating over getAllWorkflows() here because we want to include
// retired workflows, and the workflows variable does not include retired workflows
boolean isValidPatientState = false;
for (ProgramWorkflow wf : patientProgram.getProgram().getAllWorkflows()) {
if (wf.getStates().contains(patientState.getState())) {
isValidPatientState = true;
break;
}
}
if (!isValidPatientState) {
errors.rejectValue("states", "PatientState.error.invalidPatientState", new Object[] { patientState }, null);
return;
}
// will validate it with other states in its workflow
if (!patientState.getState().getProgramWorkflow().equals(workFlow)) {
continue;
}
if (OpenmrsUtil.compareWithNullAsLatest(patientState.getEndDate(), patientState.getStartDate()) < 0) {
errors.rejectValue("states", "PatientState.error.endDateCannotBeBeforeStartDate");
return;
} else if (statesAndStartDates.contains(patientState.getState().getUuid() + "" + patientState.getStartDate())) {
// we already have a patient state with the same work flow state and start date
errors.rejectValue("states", "PatientState.error.duplicatePatientStates");
return;
}
// Ensure that the patient is only in one state at a given time
if (!foundCurrentPatientState && patientState.getEndDate() == null) {
foundCurrentPatientState = true;
} else if (foundCurrentPatientState && patientState.getEndDate() == null) {
errors.rejectValue("states", "PatientProgram.error.cannotBeInMultipleStates");
return;
}
if (latestState == null) {
latestState = patientState;
} else {
if (patientState.compareTo(latestState) > 0) {
// patient should have already left this state since it is older
if (latestState.getEndDate() == null) {
errors.rejectValue("states", "PatientProgram.error.cannotBeInMultipleStates");
return;
} else if (OpenmrsUtil.compareWithNullAsEarliest(patientState.getStartDate(), latestState.getEndDate()) < 0) {
// current state was started before a previous state was ended
errors.rejectValue("states", "PatientProgram.error.foundOverlappingStates", new Object[] { patientState.getStartDate(), latestState.getEndDate() }, null);
return;
}
latestState = patientState;
} else if (patientState.compareTo(latestState) < 0) {
// patient should have already left this state since it is older
if (patientState.getEndDate() == null) {
errors.rejectValue("states", "PatientProgram.error.cannotBeInMultipleStates");
return;
} else if (OpenmrsUtil.compareWithNullAsEarliest(latestState.getStartDate(), patientState.getEndDate()) < 0) {
// latest state was started before a previous state was ended
errors.rejectValue("states", "PatientProgram.error.foundOverlappingStates");
return;
}
}
}
statesAndStartDates.add(patientState.getState().getUuid() + "" + patientState.getStartDate());
}
}
}
ValidateUtil.validateFieldLengths(errors, obj.getClass(), "voidReason");
//
}
use of org.openmrs.PatientProgram in project openmrs-core by openmrs.
the class PatientProgramValidatorTest method validate_shouldFailIfAPatientStateHasAnInvalidWorkFlowState.
/**
* @see PatientProgramValidator#validate(Object,Errors)
*/
@Test
public void validate_shouldFailIfAPatientStateHasAnInvalidWorkFlowState() {
executeDataSet("org/openmrs/api/include/ProgramWorkflowServiceTest-otherProgramWorkflows.xml");
PatientProgram program = Context.getProgramWorkflowService().getPatientProgram(1);
PatientState patientState = program.getStates().iterator().next();
patientState.setState(Context.getProgramWorkflowService().getStateByUuid("31c82d66-245c-11e1-9cf0-00248140a5eb"));
BindException errors = new BindException(program, "");
new PatientProgramValidator().validate(program, errors);
Assert.assertTrue(errors.hasFieldErrors("states"));
}
use of org.openmrs.PatientProgram in project openmrs-core by openmrs.
the class PatientProgramValidatorTest method validate_shouldFailIfThereIsMoreThanOneStateWithANullStartDateInTheSameWorkflow.
/**
* @see PatientProgramValidator#validate(Object,Errors)
*/
@Test
public void validate_shouldFailIfThereIsMoreThanOneStateWithANullStartDateInTheSameWorkflow() {
ProgramWorkflowService pws = Context.getProgramWorkflowService();
Patient patient = Context.getPatientService().getPatient(6);
PatientProgram pp = new PatientProgram();
pp.setPatient(patient);
pp.setProgram(pws.getProgram(1));
ProgramWorkflow testWorkflow = pp.getProgram().getWorkflow(1);
// Add 2 other patient states with null start date
PatientState newPatientState1 = new PatientState();
newPatientState1.setState(testWorkflow.getState(1));
pp.getStates().add(newPatientState1);
PatientState newPatientState2 = new PatientState();
newPatientState2.setState(testWorkflow.getState(2));
pp.getStates().add(newPatientState2);
BindException errors = new BindException(pp, "");
new PatientProgramValidator().validate(pp, errors);
Assert.assertEquals(true, errors.hasFieldErrors("states"));
}
Aggregations