Search in sources :

Example 21 with PatientProgram

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));
}
Also used : PatientProgram(org.openmrs.PatientProgram) Program(org.openmrs.Program) PatientProgram(org.openmrs.PatientProgram) Test(org.junit.Test) BaseContextSensitiveTest(org.openmrs.test.BaseContextSensitiveTest)

Example 22 with PatientProgram

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;
}
Also used : ProgramWorkflow(org.openmrs.ProgramWorkflow) PatientProgram(org.openmrs.PatientProgram) Program(org.openmrs.Program) HashMap(java.util.HashMap) ProgramWorkflowService(org.openmrs.api.ProgramWorkflowService) ArrayList(java.util.ArrayList) Patient(org.openmrs.Patient) PatientProgram(org.openmrs.PatientProgram) PatientIdentifier(org.openmrs.PatientIdentifier) Date(java.util.Date) PatientState(org.openmrs.PatientState) PatientService(org.openmrs.api.PatientService) ProgramWorkflowState(org.openmrs.ProgramWorkflowState) PatientIdentifierType(org.openmrs.PatientIdentifierType)

Example 23 with PatientProgram

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");
// 
}
Also used : ProgramWorkflow(org.openmrs.ProgramWorkflow) MessageSourceService(org.openmrs.messagesource.MessageSourceService) PatientProgram(org.openmrs.PatientProgram) Date(java.util.Date) PatientState(org.openmrs.PatientState) HashSet(java.util.HashSet)

Example 24 with PatientProgram

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"));
}
Also used : BindException(org.springframework.validation.BindException) PatientProgram(org.openmrs.PatientProgram) PatientState(org.openmrs.PatientState) Test(org.junit.Test) BaseContextSensitiveTest(org.openmrs.test.BaseContextSensitiveTest)

Example 25 with PatientProgram

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"));
}
Also used : ProgramWorkflow(org.openmrs.ProgramWorkflow) ProgramWorkflowService(org.openmrs.api.ProgramWorkflowService) Patient(org.openmrs.Patient) BindException(org.springframework.validation.BindException) PatientProgram(org.openmrs.PatientProgram) PatientState(org.openmrs.PatientState) Test(org.junit.Test) BaseContextSensitiveTest(org.openmrs.test.BaseContextSensitiveTest)

Aggregations

PatientProgram (org.openmrs.PatientProgram)37 Test (org.junit.Test)30 BaseContextSensitiveTest (org.openmrs.test.BaseContextSensitiveTest)27 BindException (org.springframework.validation.BindException)18 PatientState (org.openmrs.PatientState)17 Date (java.util.Date)14 Patient (org.openmrs.Patient)11 ProgramWorkflowService (org.openmrs.api.ProgramWorkflowService)7 Program (org.openmrs.Program)6 ProgramWorkflow (org.openmrs.ProgramWorkflow)5 ArrayList (java.util.ArrayList)3 ProgramWorkflowState (org.openmrs.ProgramWorkflowState)3 MissingPropertyException (groovy.lang.MissingPropertyException)1 SimpleDateFormat (java.text.SimpleDateFormat)1 Calendar (java.util.Calendar)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 ObjectMapper (org.codehaus.jackson.map.ObjectMapper)1 ObjectNode (org.codehaus.jackson.node.ObjectNode)1 DateTime (org.joda.time.DateTime)1