Search in sources :

Example 6 with PatientState

use of org.openmrs.PatientState in project openmrs-core by openmrs.

the class PatientProgramValidatorTest method validate_shouldPassIfTheStartDateOfTheFirstPatientStateInTheWorkFlowIsNull.

/**
 * @see PatientProgramValidator#validate(Object,Errors)
 */
@Test
public void validate_shouldPassIfTheStartDateOfTheFirstPatientStateInTheWorkFlowIsNull() {
    PatientProgram program = Context.getProgramWorkflowService().getPatientProgram(1);
    // sanity check
    Assert.assertEquals(1, program.getStates().size());
    PatientState patientState = program.getStates().iterator().next();
    patientState.setStartDate(null);
    BindException errors = new BindException(program, "");
    new PatientProgramValidator().validate(program, errors);
    Assert.assertEquals(false, 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 7 with PatientState

use of org.openmrs.PatientState in project openmrs-core by openmrs.

the class ProgramWorkflowServiceImpl method unvoidPatientProgram.

/**
 * @see org.openmrs.api.ProgramWorkflowService#voidPatientProgram(org.openmrs.PatientProgram,
 *      java.lang.String)
 */
@Override
public PatientProgram unvoidPatientProgram(PatientProgram patientProgram) {
    Date voidDate = patientProgram.getDateVoided();
    patientProgram.setVoided(false);
    for (PatientState state : patientProgram.getStates()) {
        if (voidDate != null && voidDate.equals(state.getDateVoided())) {
            state.setVoided(false);
            state.setVoidedBy(null);
            state.setDateVoided(null);
            state.setVoidReason(null);
        }
    }
    // The savePatientProgram method handles all of the unvoiding defaults
    return Context.getProgramWorkflowService().savePatientProgram(patientProgram);
}
Also used : Date(java.util.Date) PatientState(org.openmrs.PatientState)

Example 8 with PatientState

use of org.openmrs.PatientState in project openmrs-core by openmrs.

the class ProgramWorkflowServiceTest method getPatientStateByUuid_shouldFindObjectGivenValidUuid.

/**
 * @see ProgramWorkflowService#getPatientStateByUuid(String)
 */
@Test
public void getPatientStateByUuid_shouldFindObjectGivenValidUuid() {
    String uuid = "ea89deaa-23cc-4840-92fe-63d199c37e4c";
    PatientState patientState = Context.getProgramWorkflowService().getPatientStateByUuid(uuid);
    Assert.assertEquals(1, (int) patientState.getPatientStateId());
}
Also used : PatientState(org.openmrs.PatientState) Test(org.junit.Test) BaseContextSensitiveTest(org.openmrs.test.BaseContextSensitiveTest)

Example 9 with PatientState

use of org.openmrs.PatientState 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 10 with PatientState

use of org.openmrs.PatientState 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)

Aggregations

PatientState (org.openmrs.PatientState)19 PatientProgram (org.openmrs.PatientProgram)17 Test (org.junit.Test)15 BaseContextSensitiveTest (org.openmrs.test.BaseContextSensitiveTest)14 BindException (org.springframework.validation.BindException)11 Date (java.util.Date)7 ProgramWorkflow (org.openmrs.ProgramWorkflow)5 Patient (org.openmrs.Patient)3 ProgramWorkflowState (org.openmrs.ProgramWorkflowState)3 ProgramWorkflowService (org.openmrs.api.ProgramWorkflowService)3 ArrayList (java.util.ArrayList)1 Calendar (java.util.Calendar)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 PatientIdentifier (org.openmrs.PatientIdentifier)1 PatientIdentifierType (org.openmrs.PatientIdentifierType)1 Program (org.openmrs.Program)1 APIException (org.openmrs.api.APIException)1 PatientService (org.openmrs.api.PatientService)1 MessageSourceService (org.openmrs.messagesource.MessageSourceService)1