← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 12018: (Person-API) allow program filtering in /api/persons

 

------------------------------------------------------------
revno: 12018
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Tue 2013-09-10 15:10:10 +0200
message:
  (Person-API) allow program filtering in /api/persons
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientStore.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/event/AbstractPersonService.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/event/PersonService.java
  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/hibernate/HibernatePatientStore.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/event/PersonController.java


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== 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-09-10 12:18:56 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientService.java	2013-09-10 13:10:10 +0000
@@ -130,6 +130,38 @@
     Collection<Patient> getPatients( OrganisationUnit organisationUnit );
 
     /**
+     *
+     * @param program
+     * @return
+     */
+    Collection<Patient> getPatients( Program program );
+
+    /**
+     *
+     * @param program
+     * @param gender
+     * @return
+     */
+    Collection<Patient> getPatients( Program program, String gender );
+
+    /**
+     *
+     * @param organisationUnit
+     * @param program
+     * @param gender
+     * @return
+     */
+    Collection<Patient> getPatients( OrganisationUnit organisationUnit, Program program, String gender );
+
+    /**
+     *
+     * @param organisationUnit
+     * @param program
+     * @return
+     */
+    Collection<Patient> getPatients( OrganisationUnit organisationUnit, Program program );
+
+    /**
      * Search Patient base on organization unit with result limited
      *
      * @param organisationUnit organisationUnit
@@ -257,5 +289,4 @@
 
     Grid getTrackingEventsReport( Program program, List<String> searchKeys, Collection<OrganisationUnit> orgunit,
         Boolean followup, I18n i18n );
-
 }

=== 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-09-10 12:18:56 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientStore.java	2013-09-10 13:10:10 +0000
@@ -93,5 +93,9 @@
         Collection<PatientAttribute> patientAttributes, Collection<PatientIdentifierType> identifierTypes, Integer min,
         Integer max );
 
-
+    Collection<Patient> getByOrgUnitProgramGender( OrganisationUnit organisationUnit, Program program, String gender, int min, int max );
+
+    Collection<Patient> getByProgram( Program program, int min, int max );
+
+    Collection<Patient> getByProgram( Program program, String gender, int min, int max );
 }

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/event/AbstractPersonService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/event/AbstractPersonService.java	2013-09-10 12:18:56 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/event/AbstractPersonService.java	2013-09-10 13:10:10 +0000
@@ -33,6 +33,7 @@
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.patient.Patient;
 import org.hisp.dhis.patient.PatientService;
+import org.hisp.dhis.program.Program;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -67,47 +68,57 @@
     @Override
     public Persons getPersons()
     {
-        Persons persons = new Persons();
-
-        // TODO replace with sql, will be very bad performance when identifiers, attributes etc are included
         List<Patient> patients = new ArrayList<Patient>( patientService.getAllPatients() );
-
-        for ( Patient patient : patients )
-        {
-            persons.getPersons().add( getPerson( patient ) );
-        }
-
-        return persons;
+        return getPersons( patients );
     }
 
     @Override
     public Persons getPersons( OrganisationUnit organisationUnit )
     {
-        Persons persons = new Persons();
-
         List<Patient> patients = new ArrayList<Patient>( patientService.getPatients( organisationUnit ) );
-
-        for ( Patient patient : patients )
-        {
-            persons.getPersons().add( getPerson( patient ) );
-        }
-
-        return persons;
+        return getPersons( patients );
+    }
+
+    @Override
+    public Persons getPersons( Gender gender )
+    {
+        List<Patient> patients = new ArrayList<Patient>( patientService.getPatiensByGender( gender.getValue() ) );
+        return getPersons( patients );
+    }
+
+    @Override
+    public Persons getPersons( Program program )
+    {
+        List<Patient> patients = new ArrayList<Patient>( patientService.getPatients( program ) );
+        return getPersons( patients );
+    }
+
+    @Override
+    public Persons getPersons( Program program, Gender gender )
+    {
+        List<Patient> patients = new ArrayList<Patient>( patientService.getPatients( program, gender.getValue() ) );
+        return getPersons( patients );
+    }
+
+    @Override
+    public Persons getPersons( OrganisationUnit organisationUnit, Program program )
+    {
+        List<Patient> patients = new ArrayList<Patient>( patientService.getPatients( organisationUnit, program ) );
+        return getPersons( patients );
     }
 
     @Override
     public Persons getPersons( OrganisationUnit organisationUnit, Gender gender )
     {
-        Persons persons = new Persons();
-
         List<Patient> patients = new ArrayList<Patient>( patientService.getPatients( organisationUnit, gender.getValue() ) );
-
-        for ( Patient patient : patients )
-        {
-            persons.getPersons().add( getPerson( patient ) );
-        }
-
-        return persons;
+        return getPersons( patients );
+    }
+
+    @Override
+    public Persons getPersons( OrganisationUnit organisationUnit, Program program, Gender gender )
+    {
+        List<Patient> patients = new ArrayList<Patient>( patientService.getPatients( organisationUnit, program, gender.getValue() ) );
+        return getPersons( patients );
     }
 
     @Override

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/event/PersonService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/event/PersonService.java	2013-09-10 12:18:56 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/event/PersonService.java	2013-09-10 13:10:10 +0000
@@ -30,6 +30,7 @@
 
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.patient.Patient;
+import org.hisp.dhis.program.Program;
 
 import java.util.Collection;
 
@@ -42,8 +43,18 @@
 
     Persons getPersons( OrganisationUnit organisationUnit );
 
+    Persons getPersons( Gender gender );
+
+    Persons getPersons( Program program );
+
+    Persons getPersons( Program program, Gender gender );
+
+    Persons getPersons( OrganisationUnit organisationUnit, Program program );
+
     Persons getPersons( OrganisationUnit organisationUnit, Gender gender );
 
+    Persons getPersons( OrganisationUnit organisationUnit, Program program, Gender gender );
+
     Persons getPersons( Collection<Patient> patients );
 
     Person getPerson( String uid );

=== 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-09-10 12:18:56 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/DefaultPatientService.java	2013-09-10 13:10:10 +0000
@@ -298,6 +298,30 @@
     }
 
     @Override
+    public Collection<Patient> getPatients( Program program )
+    {
+        return patientStore.getByProgram( program, 0, Integer.MAX_VALUE );
+    }
+
+    @Override
+    public Collection<Patient> getPatients( Program program, String gender )
+    {
+        return patientStore.getByProgram( program, gender, 0, Integer.MAX_VALUE );
+    }
+
+    @Override
+    public Collection<Patient> getPatients( OrganisationUnit organisationUnit, Program program, String gender )
+    {
+        return patientStore.getByOrgUnitProgramGender( organisationUnit, program, gender, 0, Integer.MAX_VALUE );
+    }
+
+    @Override
+    public Collection<Patient> getPatients( OrganisationUnit organisationUnit, Program program )
+    {
+        return patientStore.getByOrgUnitProgram( organisationUnit, program, 0, Integer.MAX_VALUE );
+    }
+
+    @Override
     public Collection<Patient> getPatients( OrganisationUnit organisationUnit, String gender, Integer min, Integer max )
     {
         return patientStore.getByOrgUnitAndGender( organisationUnit, gender, min, max );

=== 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-09-10 12:18:56 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/hibernate/HibernatePatientStore.java	2013-09-10 13:10:10 +0000
@@ -215,11 +215,11 @@
         if ( organisationUnit != null )
         {
             criteria = getCriteria( Restrictions.eq( "organisationUnit", organisationUnit ) ).createAlias(
-            "programs", "program" ).add( Restrictions.eq( "program.id", program.getId() ) );
+                "programs", "program" ).add( Restrictions.eq( "program.id", program.getId() ) );
         }
         else
         {
-            criteria = getCriteria().createAlias("programs", "program" ).add( Restrictions.eq( "program.id", program.getId() ) );
+            criteria = getCriteria().createAlias( "programs", "program" ).add( Restrictions.eq( "program.id", program.getId() ) );
         }
         criteria.addOrder( Order.desc( "id" ) );
 
@@ -231,6 +231,53 @@
     }
 
     @Override
+    @SuppressWarnings( "unchecked" )
+    public Collection<Patient> getByOrgUnitProgramGender( OrganisationUnit organisationUnit, Program program, String gender, int min, int max )
+    {
+        String hql = "select p from Patient p where p.organisationUnit = :organisationUnit and p.gender = :gender "
+            + " and :program member of p.programs"
+            + " order by p.id DESC";
+
+        Query query = getQuery( hql );
+        query.setEntity( "organisationUnit", organisationUnit );
+        query.setEntity( "program", program );
+        query.setString( "gender", gender );
+
+        query.setFirstResult( min ).setMaxResults( max );
+
+        return query.list();
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public Collection<Patient> getByProgram( Program program, int min, int max )
+    {
+        String hql = "select p from Patient p where :program member of p.programs order by p.id DESC";
+
+        Query query = getQuery( hql );
+        query.setEntity( "program", program );
+
+        query.setFirstResult( min ).setMaxResults( max );
+
+        return query.list();
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public Collection<Patient> getByProgram( Program program, String gender, int min, int max )
+    {
+        String hql = "select p from Patient p where p.gender = :gender and :program member of p.programs order by p.id DESC";
+
+        Query query = getQuery( hql );
+        query.setString( "gender", gender );
+        query.setEntity( "program", program );
+
+        query.setFirstResult( min ).setMaxResults( max );
+
+        return query.list();
+    }
+
+    @Override
     public int countGetPatientsByName( String fullName )
     {
         fullName = fullName.toLowerCase();
@@ -509,103 +556,103 @@
                     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 ";
+                        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 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;
+                            // 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 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() )
@@ -626,20 +673,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 + " ";

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/event/PersonController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/event/PersonController.java	2013-09-10 12:18:56 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/event/PersonController.java	2013-09-10 13:10:10 +0000
@@ -35,13 +35,16 @@
 import org.hisp.dhis.dxf2.event.PersonService;
 import org.hisp.dhis.dxf2.event.Persons;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.program.Program;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.client.HttpClientErrorException;
 
 import javax.servlet.http.HttpServletRequest;
 import java.util.Map;
@@ -63,27 +66,55 @@
 
     @RequestMapping( value = "", method = RequestMethod.GET )
     public String getPersons(
-        @RequestParam( required = false ) String orgUnit,
+        @RequestParam( value = "orgUnit", required = false ) String orgUnitUid,
         @RequestParam( required = false ) Gender gender,
+        @RequestParam( value = "program", required = false ) String programUid,
         @RequestParam Map<String, String> parameters, Model model, HttpServletRequest request ) throws Exception
     {
         WebOptions options = new WebOptions( parameters );
         Persons persons;
 
-        // it will be required in the future to have at least orgUnit, but for now, we allow no parameters
-        if ( gender == null && orgUnit == null )
+        // it will be required in the future to have at least orgUnitUid, but for now, we allow no parameters
+        if ( gender == null && orgUnitUid == null && programUid == null )
         {
             persons = personService.getPersons();
         }
-        else if ( gender != null )
-        {
-            OrganisationUnit organisationUnit = manager.get( OrganisationUnit.class, orgUnit );
+        else if ( orgUnitUid != null && programUid != null && gender != null )
+        {
+            OrganisationUnit organisationUnit = getOrganisationUnit( orgUnitUid );
+            Program program = getProgram( programUid );
+            persons = personService.getPersons( organisationUnit, program, gender );
+        }
+        else if ( orgUnitUid != null && gender != null )
+        {
+            OrganisationUnit organisationUnit = getOrganisationUnit( orgUnitUid );
             persons = personService.getPersons( organisationUnit, gender );
         }
+        else if ( orgUnitUid != null && programUid != null )
+        {
+            OrganisationUnit organisationUnit = getOrganisationUnit( orgUnitUid );
+            Program program = getProgram( programUid );
+
+            persons = personService.getPersons( organisationUnit, program );
+        }
+        else if ( programUid != null && gender != null )
+        {
+            Program program = getProgram( programUid );
+            persons = personService.getPersons( program, gender );
+        }
+        else if ( orgUnitUid != null )
+        {
+            OrganisationUnit organisationUnit = getOrganisationUnit( orgUnitUid );
+            persons = personService.getPersons( organisationUnit );
+        }
+        else if ( programUid != null )
+        {
+            Program program = getProgram( programUid );
+            persons = personService.getPersons( program );
+        }
         else
         {
-            OrganisationUnit organisationUnit = manager.get( OrganisationUnit.class, orgUnit );
-            persons = personService.getPersons( organisationUnit );
+            persons = new Persons();
         }
 
         model.addAttribute( "model", persons );
@@ -92,6 +123,30 @@
         return "persons";
     }
 
+    private Program getProgram( String programUid )
+    {
+        Program program = manager.get( Program.class, programUid );
+
+        if ( program == null )
+        {
+            throw new HttpClientErrorException( HttpStatus.BAD_REQUEST, "program is not valid uid." );
+        }
+
+        return program;
+    }
+
+    private OrganisationUnit getOrganisationUnit( String orgUnitUid )
+    {
+        OrganisationUnit organisationUnit = manager.get( OrganisationUnit.class, orgUnitUid );
+
+        if ( organisationUnit == null )
+        {
+            throw new HttpClientErrorException( HttpStatus.BAD_REQUEST, "orgUnit is not a valid uid." );
+        }
+
+        return organisationUnit;
+    }
+
     @RequestMapping( value = "/{id}", method = RequestMethod.GET )
     public String getPerson( @PathVariable String id, @RequestParam Map<String, String> parameters, Model model, HttpServletRequest request )
     {