=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientService.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientService.java 2013-10-14 16:17:44 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientService.java 2013-10-23 12:24:18 +0000 @@ -48,6 +48,12 @@ { String ID = PatientService.class.getName(); + public static final int ERROR_NONE = 0; + + public static final int ERROR_DUPLICATE_IDENTIFIER = 1; + + public static final int ERROR_ENROLLMENT = 2; + int savePatient( Patient patient ); void deletePatient( Patient patient ); @@ -64,7 +70,7 @@ /** * Search Patient base on birthDate - * + * * @param birthDate * @return Patient List */ @@ -72,7 +78,7 @@ /** * Search Patient base on fullName - * + * * @param name fullName * @return Patient List */ @@ -80,7 +86,7 @@ /** * Search Patient base on full-name or identifier value - * + * * @param searchText value * @return Patient List */ @@ -88,7 +94,7 @@ /** * Search Patient for mobile base on identifier value - * + * * @param searchText value * @param orgUnitId * @return Patient List @@ -97,7 +103,7 @@ /** * Search Patient base on organization unit with result limited - * + * * @param organisationUnit organisationUnit * @return Patient List */ @@ -105,21 +111,21 @@ /** * Search Patient base on organization unit with result limited - * + * * @param organisationUnit organisationUnit * @return Patient List */ Collection getPatients( OrganisationUnit organisationUnit ); /** - * + * * @param program * @return */ Collection getPatients( Program program ); /** - * + * * @param organisationUnit * @param program * @return @@ -129,7 +135,7 @@ /** * Search Patient base on organization unit and sort the result by * PatientAttribute - * + * * @param organisationUnit organisationUnit * @param patientAttribute * @param min @@ -141,9 +147,9 @@ /** * Search Patient base on organisationUnit and identifier value name - * + * * @param organisationUnit - * @param searchText identifier value + * @param searchText identifier value * @param min * @param max * @return @@ -153,7 +159,7 @@ /** * Search Patient base on PatientIdentifierType or Attribute or Patient's * name - * + * * @param identifierTypeId * @param attributeId * @param value @@ -164,7 +170,7 @@ /** * Search Patient base on OrganisationUnit and Program with result limited * name - * + * * @param organisationUnit * @param program * @param min @@ -175,7 +181,7 @@ /** * Sort the result by PatientAttribute - * + * * @param patients * @param patientAttribute * @return Patient List @@ -186,16 +192,15 @@ /** * Search Patient base on identifier value and get number of result - * + * * @param searchText * @return number of patients */ int countGetPatients( String searchText ); /** - * Search Patient base on name and get number of - * result - * + * Search Patient base on name and get number of result + * * @param name * @return number of patients */ @@ -213,12 +218,13 @@ int countGetPatientsByOrgUnitProgram( OrganisationUnit organisationUnit, Program program ); Object getObjectValue( String property, String value, I18nFormat format ); - + Collection searchPatients( List searchKeys, Collection orgunit, - Boolean followup, Collection patientAttributes, Collection identifierTypes, - Integer statusEnrollment, Integer min, Integer max ); + Boolean followup, Collection patientAttributes, + Collection identifierTypes, Integer statusEnrollment, Integer min, Integer max ); - int countSearchPatients( List searchKeys, Collection orgunit, Boolean followup, Integer statusEnrollment ); + int countSearchPatients( List searchKeys, Collection orgunit, Boolean followup, + Integer statusEnrollment ); Collection getPatientPhoneNumbers( List searchKeys, Collection orgunit, Boolean followup, Integer statusEnrollment, Integer min, Integer max ); @@ -226,8 +232,8 @@ List getProgramStageInstances( List searchKeys, Collection orgunit, Boolean followup, Integer statusEnrollment, Integer min, Integer max ); - Grid getScheduledEventsReport( List searchKeys, Collection orgunits, Boolean followup, Integer statusEnrollment, - Integer min, Integer max, I18n i18n ); + Grid getScheduledEventsReport( List searchKeys, Collection orgunits, Boolean followup, + Integer statusEnrollment, Integer min, Integer max, I18n i18n ); Collection getPatientsByPhone( String phoneNumber, Integer min, Integer max ); @@ -237,4 +243,6 @@ Grid getTrackingEventsReport( Program program, List searchKeys, Collection orgunit, Boolean followup, Integer statusEnrollment, I18n i18n ); + + int validatePatient( Patient patient, Program program ); } === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientStore.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientStore.java 2013-10-14 17:16:30 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientStore.java 2013-10-23 12:24:18 +0000 @@ -45,6 +45,7 @@ extends GenericIdentifiableObjectStore { final String ID = PatientStore.class.getName(); + final int MAX_RESULTS = 50000; Collection getByBirthDate( Date birthDate ); @@ -55,7 +56,8 @@ Collection getByOrgUnit( OrganisationUnit organisationUnit, Integer min, Integer max ); - Collection getByOrgUnitAndNameLike( OrganisationUnit organisationUnit, String nameLike, Integer min, Integer max ); + Collection getByOrgUnitAndNameLike( OrganisationUnit organisationUnit, String nameLike, Integer min, + Integer max ); Collection getByOrgUnitProgram( OrganisationUnit organisationUnit, Program program, Integer min, Integer max ); @@ -68,7 +70,8 @@ int countGetPatientsByOrgUnitProgram( OrganisationUnit organisationUnit, Program program ); - int countSearch( List searchKeys, Collection orgunit, Boolean followup, Integer statusEnrollment ); + int countSearch( List searchKeys, Collection orgunit, Boolean followup, + Integer statusEnrollment ); Collection getByPhoneNumber( String phoneNumber, Integer min, Integer max ); @@ -77,14 +80,18 @@ Collection getRegistrationOrgunitIds( Date startDate, Date endDate ); Collection search( List searchKeys, Collection orgunit, Boolean followup, - Collection patientAttributes, Collection identifierTypes, Integer statusEnrollment, Integer min, Integer max ); + Collection patientAttributes, Collection identifierTypes, + Integer statusEnrollment, Integer min, Integer max ); - List getProgramStageInstances( List searchKeys, Collection orgunits, Boolean followup, - Collection patientAttributes, Collection identifierTypes, Integer statusEnrollment, Integer min, - Integer max ); + List getProgramStageInstances( List searchKeys, Collection orgunits, + Boolean followup, Collection patientAttributes, + Collection identifierTypes, Integer statusEnrollment, Integer min, Integer max ); Collection getByProgram( Program program, Integer min, Integer max ); - - Grid getPatientEventReport( Grid grid, List searchKeys, Collection orgunit, Boolean followup, - Collection patientAttributes, Collection identifierTypes, Integer statusEnrollment, Integer min, Integer max ); + + Grid getPatientEventReport( Grid grid, List searchKeys, Collection orgunit, + Boolean followup, Collection patientAttributes, + Collection identifierTypes, Integer statusEnrollment, Integer min, Integer max ); + + int validate( Patient patient, Program program ); } === modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/DefaultPatientService.java' --- dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/DefaultPatientService.java 2013-10-14 17:16:30 +0000 +++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/DefaultPatientService.java 2013-10-23 12:24:18 +0000 @@ -319,7 +319,8 @@ } @Override - public Collection getPatientsLikeName( OrganisationUnit organisationUnit, String name, Integer min, Integer max ) + public Collection getPatientsLikeName( OrganisationUnit organisationUnit, String name, Integer min, + Integer max ) { return patientStore.getByOrgUnitAndNameLike( organisationUnit, name, min, max ); } @@ -529,10 +530,11 @@ } public Collection searchPatients( List searchKeys, Collection orgunits, - Boolean followup, Collection patientAttributes, Collection identifierTypes, - Integer statusEnrollment, Integer min, Integer max ) + Boolean followup, Collection patientAttributes, + Collection identifierTypes, Integer statusEnrollment, Integer min, Integer max ) { - return patientStore.search( searchKeys, orgunits, followup, patientAttributes, identifierTypes, statusEnrollment, min, max ); + return patientStore.search( searchKeys, orgunits, followup, patientAttributes, identifierTypes, + statusEnrollment, min, max ); } public int countSearchPatients( List searchKeys, Collection orgunits, Boolean followup, @@ -544,10 +546,11 @@ public Collection getPatientPhoneNumbers( List searchKeys, Collection orgunits, Boolean followup, Integer statusEnrollment, Integer min, Integer max ) { - Collection patients = patientStore.search( searchKeys, orgunits, followup, null, null, statusEnrollment, min, max ); - + Collection patients = patientStore.search( searchKeys, orgunits, followup, null, null, + statusEnrollment, min, max ); + Set phoneNumbers = new HashSet(); - + for ( Patient patient : patients ) { if ( patient.getPhoneNumber() != null ) @@ -555,7 +558,7 @@ phoneNumbers.add( patient.getPhoneNumber() ); } } - + return phoneNumbers; } @@ -672,4 +675,10 @@ { return patientStore.getRegistrationOrgunitIds( startDate, endDate ); } + + @Override + public int validatePatient( Patient patient, Program program ) + { + return patientStore.validate( patient, program ); + } } === modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/hibernate/HibernatePatientStore.java' --- dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/hibernate/HibernatePatientStore.java 2013-10-16 10:03:02 +0000 +++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/hibernate/HibernatePatientStore.java 2013-10-23 12:24:18 +0000 @@ -52,6 +52,7 @@ import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.criterion.Conjunction; +import org.hibernate.criterion.Disjunction; import org.hibernate.criterion.Order; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; @@ -61,13 +62,17 @@ import org.hisp.dhis.organisationunit.OrganisationUnitService; import org.hisp.dhis.patient.Patient; import org.hisp.dhis.patient.PatientAttribute; +import org.hisp.dhis.patient.PatientIdentifier; import org.hisp.dhis.patient.PatientIdentifierType; +import org.hisp.dhis.patient.PatientService; import org.hisp.dhis.patient.PatientStore; +import org.hisp.dhis.period.Period; import org.hisp.dhis.program.Program; import org.hisp.dhis.program.ProgramInstance; import org.hisp.dhis.program.ProgramStageInstance; import org.hisp.dhis.system.grid.GridUtils; import org.hisp.dhis.system.util.TextUtils; +import org.hisp.dhis.validation.ValidationCriteria; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.transaction.annotation.Transactional; @@ -81,7 +86,7 @@ implements PatientStore { private static final Log log = LogFactory.getLog( HibernatePatientStore.class ); - + // ------------------------------------------------------------------------- // Dependencies // ------------------------------------------------------------------------- @@ -144,7 +149,7 @@ { query.setFirstResult( min ).setMaxResults( max ); } - + return query.list(); } @@ -164,44 +169,38 @@ { query.setFirstResult( min ).setMaxResults( max ); } - + return query.list(); } @Override - @SuppressWarnings("unchecked") + @SuppressWarnings( "unchecked" ) public Collection getByOrgUnitProgram( OrganisationUnit organisationUnit, Program program, Integer min, Integer max ) { - String hql = - "select pt from Patient pt " + - "inner join pt.programInstances pi " + - "where pt.organisationUnit = :organisationUnit " + - "and pi.program = :program " + - "and pi.status = :status"; - + String hql = "select pt from Patient pt " + "inner join pt.programInstances pi " + + "where pt.organisationUnit = :organisationUnit " + "and pi.program = :program " + + "and pi.status = :status"; + Query query = getQuery( hql ); query.setEntity( "organisationUnit", organisationUnit ); query.setEntity( "program", program ); query.setInteger( "status", ProgramInstance.STATUS_ACTIVE ); - + return query.list(); } @Override - @SuppressWarnings("unchecked") + @SuppressWarnings( "unchecked" ) public Collection getByProgram( Program program, Integer min, Integer max ) { - String hql = - "select pt from Patient pt " + - "inner join pt.programInstances pi " + - "where pi.program = :program " + - "and pi.status = :status"; - + String hql = "select pt from Patient pt " + "inner join pt.programInstances pi " + + "where pi.program = :program " + "and pi.status = :status"; + Query query = getQuery( hql ); query.setEntity( "program", program ); query.setInteger( "status", ProgramInstance.STATUS_ACTIVE ); - + return query.list(); } @@ -246,10 +245,10 @@ } @Override - //TODO this method must be changed - cannot retrieve one by one + // TODO this method must be changed - cannot retrieve one by one public Collection search( List searchKeys, Collection orgunits, - Boolean followup, Collection patientAttributes, Collection identifierTypes, - Integer statusEnrollment, Integer min, Integer max ) + Boolean followup, Collection patientAttributes, + Collection identifierTypes, Integer statusEnrollment, Integer min, Integer max ) { String sql = searchPatientSql( false, searchKeys, orgunits, followup, patientAttributes, identifierTypes, statusEnrollment, min, max ); @@ -274,8 +273,8 @@ @Override public List getProgramStageInstances( List searchKeys, Collection orgunits, - Boolean followup, Collection patientAttributes, Collection identifierTypes, - Integer statusEnrollment, Integer min, Integer max ) + Boolean followup, Collection patientAttributes, + Collection identifierTypes, Integer statusEnrollment, Integer min, Integer max ) { String sql = searchPatientSql( false, searchKeys, orgunits, followup, patientAttributes, identifierTypes, statusEnrollment, min, max ); @@ -306,7 +305,7 @@ String sql = searchPatientSql( true, searchKeys, orgunits, followup, null, null, statusEnrollment, null, null ); return jdbcTemplate.queryForObject( sql, Integer.class ); } - + @Override public Grid getPatientEventReport( Grid grid, List searchKeys, Collection orgunits, Boolean followup, Collection patientAttributes, @@ -321,7 +320,7 @@ return grid; } - + @Override @SuppressWarnings( "unchecked" ) public Collection getByPhoneNumber( String phoneNumber, Integer min, Integer max ) @@ -338,16 +337,16 @@ } @Override - @SuppressWarnings("unchecked") + @SuppressWarnings( "unchecked" ) public Collection getByFullName( String name, OrganisationUnit organisationUnit ) { Criteria criteria = getCriteria( Restrictions.eq( "name", name ).ignoreCase() ); - + if ( organisationUnit != null ) { criteria.add( Restrictions.eq( "organisationUnit", organisationUnit ) ); } - + return criteria.setMaxResults( MAX_RESULTS ).list(); } @@ -363,6 +362,77 @@ return criteria.list(); } + public int validate( Patient patient, Program program ) + { + Criteria criteria = getCriteria(); + criteria.createAlias( "identifiers", "patientIdentifier" ); + criteria.createAlias( "organisationUnit", "orgunit" ); + criteria.createAlias( "programInstances", "programInstance" ); + criteria.createAlias( "programInstance.program", "program" ); + + if ( patient.getIdentifiers() != null && patient.getIdentifiers().size() > 0 ) + { + Disjunction disjunction = Restrictions.disjunction(); + + for ( PatientIdentifier identifier : patient.getIdentifiers() ) + { + PatientIdentifierType patientIdentifierType = identifier.getIdentifierType(); + + Conjunction conjunction = Restrictions.conjunction(); + conjunction.add( Restrictions.eq( "patientIdentifier.identifier", identifier.getIdentifier() ) ); + conjunction.add( Restrictions.eq( "patientIdentifier.identifierType", patientIdentifierType ) ); + + if ( patient.getId() != 0 ) + { + conjunction.add( Restrictions.ne( "id", patient.getId() ) ); + } + + if ( patientIdentifierType.getType().equals( PatientIdentifierType.VALUE_TYPE_LOCAL_ID ) + && patientIdentifierType.getOrgunitScope() ) + { + conjunction.add( Restrictions.eq( "orgunit.id", patient.getOrganisationUnit().getId() ) ); + } + + if ( program != null + && patientIdentifierType.getType().equals( PatientIdentifierType.VALUE_TYPE_LOCAL_ID ) + && patientIdentifierType.getProgramScope() ) + { + conjunction.add( Restrictions.eq( "program", program ) ); + } + + if ( patientIdentifierType.getType().equals( PatientIdentifierType.VALUE_TYPE_LOCAL_ID ) + && patientIdentifierType.getPeriodType() != null ) + { + Date currentDate = new Date(); + Period period = patientIdentifierType.getPeriodType().createPeriod( currentDate ); + conjunction + .add( Restrictions.between( "enrollmentdate", period.getStartDate(), period.getEndDate() ) ); + } + + disjunction.add( conjunction ); + } + + criteria.add( disjunction ); + + if ( criteria.list() != null ) + { + return PatientService.ERROR_DUPLICATE_IDENTIFIER; + } + } + + if ( program != null ) + { + ValidationCriteria validationCriteria = program.isValid( patient ); + + if ( validationCriteria != null ) + { + return PatientService.ERROR_ENROLLMENT; + } + } + + return PatientService.ERROR_NONE; + } + // ------------------------------------------------------------------------- // Supportive methods TODO Remplement all this! // ------------------------------------------------------------------------- @@ -388,7 +458,8 @@ for ( PatientAttribute patientAttribute : patientAttributes ) { sql += "(select value from patientattributevalue where patientid=p.patientid and patientattributeid=" - + patientAttribute.getId() + " ) as " + PREFIX_PATIENT_ATTRIBUTE + "_" + patientAttribute.getId() + " ,"; + + patientAttribute.getId() + " ) as " + PREFIX_PATIENT_ATTRIBUTE + "_" + patientAttribute.getId() + + " ,"; } } @@ -428,7 +499,7 @@ if ( keys[0].equals( PREFIX_FIXED_ATTRIBUTE ) ) { patientWhere += patientOperator; - + if ( id.equals( FIXED_ATTR_BIRTH_DATE ) ) { patientWhere += " p." + id + value; @@ -455,10 +526,11 @@ String opt = ""; for ( String v : keyValues ) { - patientWhere += opt + " lower( p.name ) like '%" + v + "%' or ( lower(pi.identifier) like '%" + v + "%' and pi.patientidentifiertypeid is not null ) "; + patientWhere += opt + " lower( p.name ) like '%" + v + "%' or ( lower(pi.identifier) like '%" + v + + "%' and pi.patientidentifiertypeid is not null ) "; opt = "or"; } - + patientWhere += ")"; patientOperator = " and "; hasIdentifier = true; @@ -471,26 +543,25 @@ String[] keyValues = value.split( " " ); otherWhere += operator + "("; String opt = ""; - + for ( String v : keyValues ) { - otherWhere += opt + " lower(" + PREFIX_PATIENT_ATTRIBUTE + "_" + id + ") like '%" + v - + "%'"; + otherWhere += opt + " lower(" + PREFIX_PATIENT_ATTRIBUTE + "_" + id + ") like '%" + v + "%'"; opt = "or"; } - + otherWhere += ")"; operator = " and "; } else if ( keys[0].equals( PREFIX_PROGRAM ) ) { sql += "(select programid from programinstance pi where patientid=p.patientid and programid=" + id; - + if ( statusEnrollment != null ) { sql += " and pi.status=" + statusEnrollment; } - + sql += " limit 1 ) as " + PREFIX_PROGRAM + "_" + id + ","; otherWhere += operator + PREFIX_PROGRAM + "_" + id + "=" + id; operator = " and "; @@ -498,7 +569,7 @@ else if ( keys[0].equals( PREFIX_PROGRAM_INSTANCE ) ) { sql += "(select pi." + id + " from programinstance pi where patientid=p.patientid and pi.status=0 "; - + if ( keys.length == 5 ) { sql += " and pi.programid=" + keys[4]; @@ -507,7 +578,7 @@ { sql += " limit 1 "; } - + sql += ") as " + PREFIX_PROGRAM_INSTANCE + "_" + id + ","; otherWhere += operator + PREFIX_PROGRAM_INSTANCE + "_" + id + keys[2]; operator = " and "; @@ -528,123 +599,123 @@ int statusEvent = Integer.parseInt( keys[index] ); switch ( statusEvent ) { - case ProgramStageInstance.COMPLETED_STATUS: - patientWhere += condition + operatorStatus - + "( psi.executiondate is not null and psi.executiondate>='" + keys[2] - + "' and psi.executiondate<='" + keys[3] + "' and psi.completed=true "; - - // get events by orgunit children - if ( keys[4].equals( "-1" ) ) - { - patientWhere += " and psi.organisationunitid in( " - + TextUtils.getCommaDelimitedString( orgunitChilrenIds ) + " )"; - } - - // get events by selected orgunit - else if ( !keys[4].equals( "0" ) ) - { - patientWhere += " and psi.organisationunitid=" + keys[4]; - } - - patientWhere += ")"; - operatorStatus = " OR "; - condition = ""; - continue; - case ProgramStageInstance.VISITED_STATUS: - patientWhere += condition + operatorStatus - + "( psi.executiondate is not null and psi.executiondate>='" + keys[2] - + "' and psi.executiondate<='" + keys[3] + "' and psi.completed=false "; - - // get events by orgunit children - if ( keys[4].equals( "-1" ) ) - { - patientWhere += " and psi.organisationunitid in( " - + TextUtils.getCommaDelimitedString( orgunitChilrenIds ) + " )"; - } - - // get events by selected orgunit - else if ( !keys[4].equals( "0" ) ) - { - patientWhere += " and psi.organisationunitid=" + keys[4]; - } - - patientWhere += ")"; - operatorStatus = " OR "; - condition = ""; - continue; - case ProgramStageInstance.FUTURE_VISIT_STATUS: - patientWhere += condition + operatorStatus + "( psi.executiondate is null and psi.duedate>='" - + keys[2] + "' and psi.duedate<='" + keys[3] - + "' and psi.status is null and (DATE(now()) - DATE(psi.duedate) <= 0) "; - - // get events by orgunit children - if ( keys[4].equals( "-1" ) ) - { - patientWhere += " and p.organisationunitid in( " - + TextUtils.getCommaDelimitedString( orgunitChilrenIds ) + " )"; - } - - // get events by selected orgunit - else if ( !keys[4].equals( "0" ) ) - { - patientWhere += " and p.organisationunitid=" + keys[4]; - } - - patientWhere += ")"; - operatorStatus = " OR "; - condition = ""; - continue; - case ProgramStageInstance.LATE_VISIT_STATUS: - patientWhere += condition + operatorStatus + "( psi.executiondate is null and psi.duedate>='" - + keys[2] + "' and psi.duedate<='" + keys[3] - + "' and psi.status is not null and (DATE(now()) - DATE(psi.duedate) > 0) "; - - // get events by orgunit children - if ( keys[4].equals( "-1" ) ) - { - patientWhere += " and p.organisationunitid in( " - + TextUtils.getCommaDelimitedString( orgunitChilrenIds ) + " )"; - } - - // get events by selected orgunit - else if ( !keys[4].equals( "0" ) ) - { - patientWhere += " and p.organisationunitid=" + keys[4]; - } - - patientWhere += ")"; - operatorStatus = " OR "; - condition = ""; - continue; - case ProgramStageInstance.SKIPPED_STATUS: - patientWhere += condition + operatorStatus + "( psi.status=5 and psi.duedate>='" + keys[2] - + "' and psi.duedate<='" + keys[3] + "' "; - - // get events by orgunit children - if ( keys[4].equals( "-1" ) ) - { - patientWhere += " and psi.organisationunitid in( " - + TextUtils.getCommaDelimitedString( orgunitChilrenIds ) + " )"; - } - - // get events by selected orgunit - else if ( !keys[4].equals( "0" ) ) - { - patientWhere += " and p.organisationunitid=" + keys[4]; - } - patientWhere += ")"; - operatorStatus = " OR "; - condition = ""; - continue; - default: - continue; + case ProgramStageInstance.COMPLETED_STATUS: + patientWhere += condition + operatorStatus + + "( psi.executiondate is not null and psi.executiondate>='" + keys[2] + + "' and psi.executiondate<='" + keys[3] + "' and psi.completed=true "; + + // get events by orgunit children + if ( keys[4].equals( "-1" ) ) + { + patientWhere += " and psi.organisationunitid in( " + + TextUtils.getCommaDelimitedString( orgunitChilrenIds ) + " )"; + } + + // get events by selected orgunit + else if ( !keys[4].equals( "0" ) ) + { + patientWhere += " and psi.organisationunitid=" + keys[4]; + } + + patientWhere += ")"; + operatorStatus = " OR "; + condition = ""; + continue; + case ProgramStageInstance.VISITED_STATUS: + patientWhere += condition + operatorStatus + + "( psi.executiondate is not null and psi.executiondate>='" + keys[2] + + "' and psi.executiondate<='" + keys[3] + "' and psi.completed=false "; + + // get events by orgunit children + if ( keys[4].equals( "-1" ) ) + { + patientWhere += " and psi.organisationunitid in( " + + TextUtils.getCommaDelimitedString( orgunitChilrenIds ) + " )"; + } + + // get events by selected orgunit + else if ( !keys[4].equals( "0" ) ) + { + patientWhere += " and psi.organisationunitid=" + keys[4]; + } + + patientWhere += ")"; + operatorStatus = " OR "; + condition = ""; + continue; + case ProgramStageInstance.FUTURE_VISIT_STATUS: + patientWhere += condition + operatorStatus + "( psi.executiondate is null and psi.duedate>='" + + keys[2] + "' and psi.duedate<='" + keys[3] + + "' and psi.status is null and (DATE(now()) - DATE(psi.duedate) <= 0) "; + + // get events by orgunit children + if ( keys[4].equals( "-1" ) ) + { + patientWhere += " and p.organisationunitid in( " + + TextUtils.getCommaDelimitedString( orgunitChilrenIds ) + " )"; + } + + // get events by selected orgunit + else if ( !keys[4].equals( "0" ) ) + { + patientWhere += " and p.organisationunitid=" + keys[4]; + } + + patientWhere += ")"; + operatorStatus = " OR "; + condition = ""; + continue; + case ProgramStageInstance.LATE_VISIT_STATUS: + patientWhere += condition + operatorStatus + "( psi.executiondate is null and psi.duedate>='" + + keys[2] + "' and psi.duedate<='" + keys[3] + + "' and psi.status is not null and (DATE(now()) - DATE(psi.duedate) > 0) "; + + // get events by orgunit children + if ( keys[4].equals( "-1" ) ) + { + patientWhere += " and p.organisationunitid in( " + + TextUtils.getCommaDelimitedString( orgunitChilrenIds ) + " )"; + } + + // get events by selected orgunit + else if ( !keys[4].equals( "0" ) ) + { + patientWhere += " and p.organisationunitid=" + keys[4]; + } + + patientWhere += ")"; + operatorStatus = " OR "; + condition = ""; + continue; + case ProgramStageInstance.SKIPPED_STATUS: + patientWhere += condition + operatorStatus + "( psi.status=5 and psi.duedate>='" + keys[2] + + "' and psi.duedate<='" + keys[3] + "' "; + + // get events by orgunit children + if ( keys[4].equals( "-1" ) ) + { + patientWhere += " and psi.organisationunitid in( " + + TextUtils.getCommaDelimitedString( orgunitChilrenIds ) + " )"; + } + + // get events by selected orgunit + else if ( !keys[4].equals( "0" ) ) + { + patientWhere += " and p.organisationunitid=" + keys[4]; + } + patientWhere += ")"; + operatorStatus = " OR "; + condition = ""; + continue; + default: + continue; } } if ( condition.isEmpty() ) { patientWhere += ")"; } - + patientWhere += " and pgi.status=" + ProgramInstance.STATUS_ACTIVE + " "; patientOperator = " and "; } @@ -658,20 +729,20 @@ int statusEvent = Integer.parseInt( keys[2] ); switch ( statusEvent ) { - case ProgramStageInstance.COMPLETED_STATUS: - patientWhere += "psi.completed=true"; - break; - case ProgramStageInstance.VISITED_STATUS: - patientWhere += "psi.executiondate is not null and psi.completed=false"; - break; - case ProgramStageInstance.FUTURE_VISIT_STATUS: - patientWhere += "psi.executiondate is null and psi.duedate >= now()"; - break; - case ProgramStageInstance.LATE_VISIT_STATUS: - patientWhere += "psi.executiondate is null and psi.duedate < now()"; - break; - default: - break; + case ProgramStageInstance.COMPLETED_STATUS: + patientWhere += "psi.completed=true"; + break; + case ProgramStageInstance.VISITED_STATUS: + patientWhere += "psi.executiondate is not null and psi.completed=false"; + break; + case ProgramStageInstance.FUTURE_VISIT_STATUS: + patientWhere += "psi.executiondate is null and psi.duedate >= now()"; + break; + case ProgramStageInstance.LATE_VISIT_STATUS: + patientWhere += "psi.executiondate is null and psi.duedate < now()"; + break; + default: + break; } patientWhere += " and pgi.status=" + ProgramInstance.STATUS_ACTIVE + " "; @@ -690,11 +761,11 @@ sql = sql.substring( 0, sql.length() - 1 ) + " "; // Removing last comma String from = " from patient p "; - + if ( isSearchEvent ) { String subSQL = " , psi.programstageinstanceid as programstageinstanceid, pgs.name as programstagename, psi.duedate as duedate "; - + if ( isPriorityEvent ) { subSQL += ",pgi.followup "; @@ -705,7 +776,7 @@ { orderBy = " ORDER BY p.patientid, p.name, duedate asc "; } - + sql = sql + subSQL + from + " inner join programinstance pgi on " + " (pgi.patientid=p.patientid) " + " inner join programstageinstance psi on (psi.programinstanceid=pgi.programinstanceid) " + " inner join programstage pgs on (pgs.programstageid=psi.programstageid) "; @@ -738,9 +809,9 @@ { sql += " limit " + max + " offset " + min; } - + log.info( "Search patient SQL: " + sql ); - + return sql; } @@ -752,7 +823,8 @@ { for ( OrganisationUnit orgunit : orgunits ) { - orgUnitIds.addAll( organisationUnitService.getOrganisationUnitHierarchy().getChildren( orgunit.getId() ) ); + orgUnitIds + .addAll( organisationUnitService.getOrganisationUnitHierarchy().getChildren( orgunit.getId() ) ); orgUnitIds.remove( orgunit.getId() ); } } === modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/patient/ValidatePatientAction.java' --- dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/patient/ValidatePatientAction.java 2013-09-24 11:21:38 +0000 +++ dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/patient/ValidatePatientAction.java 2013-10-23 12:24:18 +0000 @@ -28,7 +28,13 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import com.opensymphony.xwork2.Action; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import org.apache.struts2.ServletActionContext; @@ -46,13 +52,8 @@ import org.hisp.dhis.patientattributevalue.PatientAttributeValueService; import org.hisp.dhis.program.Program; import org.hisp.dhis.program.ProgramService; -import org.hisp.dhis.validation.ValidationCriteria; - -import javax.servlet.http.HttpServletRequest; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; + +import com.opensymphony.xwork2.Action; /** * @author Abyot Asalefew Gizaw @@ -124,6 +125,10 @@ public String execute() { + // --------------------------------------------------------------------- + // Check duplicate patients based on name, birthdate and gender + // --------------------------------------------------------------------- + if ( fullName != null ) { fullName = fullName.trim(); @@ -166,6 +171,41 @@ // Check Under age information // --------------------------------------------------------------------- + OrganisationUnit orgunit = selectionManager.getSelectedOrganisationUnit(); + Patient patient = null; + if ( id != null ) + { + patient = patientService.getPatient( id ); + } + else + { + patient = new Patient(); + } + + if ( gender != null ) + { + patient.setGender( gender ); + } + + if ( birthDate != null && !birthDate.isEmpty() ) + { + birthDate = birthDate.trim(); + patient.setBirthDate( format.parseDate( birthDate ) ); + + } + else if ( age != null ) + { + patient.setBirthDateFromAge( age, Patient.AGE_TYPE_YEAR ); + } + patient.setName( fullName ); + patient.setOrganisationUnit( orgunit ); + + Program program = null; + if ( programId != null ) + { + program = programService.getProgram( programId ); + } + if ( underAge ) { if ( representativeId == null ) @@ -182,85 +222,41 @@ HttpServletRequest request = ServletActionContext.getRequest(); - Collection identifiers = identifierTypeService.getAllPatientIdentifierTypes(); + Collection identifierTypes = identifierTypeService.getAllPatientIdentifierTypes(); - if ( identifiers != null && identifiers.size() > 0 ) + if ( identifierTypes != null && identifierTypes.size() > 0 ) { String value = null; - String idDuplicate = ""; - - for ( PatientIdentifierType idType : identifiers ) + + Set patientIdentifiers = new HashSet(); + + for ( PatientIdentifierType idType : identifierTypes ) { if ( !underAge || (underAge && !idType.isRelated()) ) { value = request.getParameter( AddPatientAction.PREFIX_IDENTIFIER + idType.getId() ); - if ( StringUtils.isNotBlank( value ) ) { - boolean isDuplicate = false; - - OrganisationUnit orgunit = (idType.getOrgunitScope()) ? selectionManager - .getSelectedOrganisationUnit() : null; - Program program = (idType.getProgramScope()) ? programService.getProgram( programId ) : null; - - isDuplicate = patientIdentifierService.checkDuplicateIdentifier( idType, value, id, - orgunit, program, idType.getPeriodType() ); - - if ( isDuplicate ) - { - idDuplicate += idType.getName() + ", "; - } + PatientIdentifier patientIdentifier = new PatientIdentifier(); + patientIdentifier.setPatient( patient ); + patientIdentifier.setIdentifierType( idType ); + patientIdentifier.setIdentifier( value ); + + patientIdentifiers.add( patientIdentifier ); } } } - if ( StringUtils.isNotBlank( idDuplicate ) ) - { - idDuplicate = StringUtils.substringBeforeLast( idDuplicate, "," ); - message = i18n.getString( "identifier_duplicate" ) + ": " + idDuplicate; - return INPUT; - } - } - - // --------------------------------------------------------------------- - // Check Enrollment for adding patient single event with registration - // --------------------------------------------------------------------- - - Patient p = new Patient(); - if ( gender != null ) - { - p.setGender( gender ); - } - - if ( birthDate != null && !birthDate.isEmpty() ) - { - birthDate = birthDate.trim(); - p.setBirthDate( format.parseDate( birthDate ) ); - - } - else if ( age != null ) - { - p.setBirthDateFromAge( age, Patient.AGE_TYPE_YEAR ); - } - - if ( programId != null ) - { - Program program = programService.getProgram( programId ); - ValidationCriteria criteria = program.isValid( p ); - - if ( criteria != null ) - { - message = i18n.getString( "patient_could_not_be_enrolled_due_to_following_enrollment_criteria" ) + ": " - + criteria.getDescription(); - return INPUT; - } - } + patient.setIdentifiers( patientIdentifiers ); + } + + int errorCode = patientService.validatePatient( patient, program ); // --------------------------------------------------------------------- // Validation success // --------------------------------------------------------------------- - message = i18n.getString( "everything_is_ok" ); + message = errorCode + " "; return SUCCESS; } === modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/resources/org/hisp/dhis/caseentry/i18n_module.properties' --- dhis-2/dhis-web/dhis-web-caseentry/src/main/resources/org/hisp/dhis/caseentry/i18n_module.properties 2013-10-21 07:40:21 +0000 +++ dhis-2/dhis-web/dhis-web-caseentry/src/main/resources/org/hisp/dhis/caseentry/i18n_module.properties 2013-10-23 12:24:18 +0000 @@ -693,4 +693,6 @@ dimension = Dimension events = Events add_filter=Add filter -relationship_description = Relationship description \ No newline at end of file +relationship_description = Relationship description +duplicate_identifier = Duplicate identifier +this_patient_could_not_be_enrolled_please_check_validation_criteria = This person could not be enrolled please check validation criteria \ No newline at end of file === modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/javascript/commons.js' --- dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/javascript/commons.js 2013-10-22 03:50:27 +0000 +++ dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/javascript/commons.js 2013-10-23 12:24:18 +0000 @@ -1068,8 +1068,16 @@ if ( type == 'success' ) { - removeDisabledIdentifier(); - updatePatient(); + if( message == 0 ){ + removeDisabledIdentifier(); + updatePatient(); + } + else if( message == 1 ){ + showErrorMessage( i18n_adding_patient_failed + ':' + '\n' + i18n_duplicate_identifier ); + } + else if( message == 2 ){ + showErrorMessage( i18n_adding_patient_failed + ':' + '\n' + i18n_this_patient_could_not_be_enrolled_please_check_validation_criteria ); + } } else { === modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/javascript/patient.js' --- dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/javascript/patient.js 2013-10-12 14:34:49 +0000 +++ dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/javascript/patient.js 2013-10-23 12:24:18 +0000 @@ -260,8 +260,16 @@ if ( type == 'success' ) { - removeDisabledIdentifier( ); - addPatient( programId, related, isContinue ); + if( message == 0 ){ + removeDisabledIdentifier( ); + addPatient( programId, related, isContinue ); + } + else if( message == 1 ){ + showErrorMessage( i18n_adding_patient_failed + ':' + '\n' + i18n_duplicate_identifier ); + } + else if( message == 2 ){ + showErrorMessage( i18n_adding_patient_failed + ':' + '\n' + i18n_this_patient_could_not_be_enrolled_please_check_validation_criteria ); + } } else { @@ -277,10 +285,10 @@ { showListPatientDuplicate(data, false); } - - $("#patientForm :input").attr("disabled", false); - $("#patientForm").find("select").attr("disabled", false); } + + $("#patientForm :input").attr("disabled", false); + $("#patientForm").find("select").attr("disabled", false); } function addRelationship() === modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/javascript/singleEvent.js' --- dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/javascript/singleEvent.js 2013-05-28 03:10:26 +0000 +++ dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/javascript/singleEvent.js 2013-10-23 12:24:18 +0000 @@ -93,8 +93,16 @@ if ( type == 'success' ) { - removeDisabledIdentifier( ); - addPatient(); + if( message == 0 ){ + removeDisabledIdentifier( ); + addPatient(); + } + else if( message == 1 ){ + showErrorMessage( i18n_adding_patient_failed + ':' + '\n' + i18n_duplicate_identifier ); + } + else if( message == 2 ){ + showErrorMessage( i18n_adding_patient_failed + ':' + '\n' + i18n_this_patient_could_not_be_enrolled_please_check_validation_criteria ); + } } else { === modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/javascript/underage.js' --- dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/javascript/underage.js 2012-12-10 12:54:54 +0000 +++ dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/javascript/underage.js 2013-10-23 12:24:18 +0000 @@ -22,20 +22,27 @@ if ( type == 'success' ) { - jQuery.ajax({ - type: "POST" - ,url: "addRepresentative.action" - ,data: jQuery("#addRepresentativeForm").serialize() - ,dataType : "xml" - ,success: function(xml){ - autoChoosePerson( xml ); - } - ,error: function() - { - alert(i18n_error_connect_to_server); - } - }); - + if( message == 0 ){ + jQuery.ajax({ + type: "POST" + ,url: "addRepresentative.action" + ,data: jQuery("#addRepresentativeForm").serialize() + ,dataType : "xml" + ,success: function(xml){ + autoChoosePerson( xml ); + } + ,error: function() + { + alert(i18n_error_connect_to_server); + } + }); + } + else if( message == 1 ){ + showErrorMessage( i18n_adding_patient_failed + ':' + '\n' + i18n_duplicate_identifier ); + } + else if( message == 2 ){ + showErrorMessage( i18n_adding_patient_failed + ':' + '\n' + i18n_this_patient_could_not_be_enrolled_please_check_validation_criteria ); + } } else if ( type == 'error' ) { === modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/selectPatient.vm' --- dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/selectPatient.vm 2013-10-22 16:57:47 +0000 +++ dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/selectPatient.vm 2013-10-23 12:24:18 +0000 @@ -108,6 +108,8 @@ var i18n_comment_added = '$encoder.jsEscape( $i18n.getString( "comment_added" ) , "'")'; var i18n_update = '$encoder.jsEscape( $i18n.getString( "update" ) , "'")'; var i18n_insert_a_report_date = '$encoder.jsEscape( $i18n.getString( "insert_a_report_date" ) , "'")'; + var i18n_duplicate_identifier = '$encoder.jsEscape( $i18n.getString( "duplicate_identifier" ) , "'")'; + var i18n_this_patient_could_not_be_enrolled_please_check_validation_criteria = '$encoder.jsEscape( $i18n.getString( "this_patient_could_not_be_enrolled_please_check_validation_criteria" ) , "'")'; var checkedDuplicate = false; // -1: no search anything === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/resources/org/hisp/dhis/patient/i18n_module.properties' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/resources/org/hisp/dhis/patient/i18n_module.properties 2013-10-21 07:40:21 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/resources/org/hisp/dhis/patient/i18n_module.properties 2013-10-23 12:24:18 +0000 @@ -480,4 +480,5 @@ shortcut_link_label_eg_add_child = Shortcut link label (e.g. Add Child) relationship = Relationship select_at_least_one_scope=Select at least one scope for local id -scheduling_of_events = Scheduling of events \ No newline at end of file +scheduling_of_events = Scheduling of events +show_advanced_options = Show advanced options \ No newline at end of file