← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 19557: replaced old Enrollment query with HQL, changed endpoint parameters from orgUnit => ou, startDate...

 

------------------------------------------------------------
revno: 19557
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Tue 2015-07-07 13:11:54 +0700
message:
  replaced old Enrollment query with HQL, changed endpoint parameters from orgUnit => ou, startDate => programStartDate, endDate => programEndDate, adds created/lastUpdated/trackedEntity to Enrollment class, also adds paging (default on)
added:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceQueryParams.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceStore.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/DefaultProgramInstanceService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/hibernate/HibernateProgramInstanceStore.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/trackedentity/hibernate/HibernateTrackedEntityInstanceStore.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/enrollment/AbstractEnrollmentService.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/enrollment/Enrollment.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/enrollment/EnrollmentService.java
  dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/util/SqlHelper.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EnrollmentController.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
=== added file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceQueryParams.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceQueryParams.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceQueryParams.java	2015-07-07 06:11:54 +0000
@@ -0,0 +1,406 @@
+package org.hisp.dhis.program;
+
+/*
+ * Copyright (c) 2004-2015, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import org.hisp.dhis.common.OrganisationUnitSelectionMode;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.trackedentity.TrackedEntity;
+import org.hisp.dhis.trackedentity.TrackedEntityInstance;
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public class ProgramInstanceQueryParams
+{
+    public static final int DEFAULT_PAGE = 1;
+    public static final int DEFAULT_PAGE_SIZE = 50;
+
+    /**
+     * Last updated for enrollment.
+     */
+    private Date lastUpdated;
+
+    /**
+     * Organisation units for which instances in the response were registered at.
+     * Is related to the specified OrganisationUnitMode.
+     */
+    private Set<OrganisationUnit> organisationUnits = new HashSet<>();
+
+    /**
+     * Selection mode for the specified organisation units.
+     */
+    private OrganisationUnitSelectionMode organisationUnitMode;
+
+    /**
+     * Program for which instances in the response must be enrolled in.
+     */
+    private Program program;
+
+    /**
+     * Status of the tracked entity instance in the given program.
+     */
+    private ProgramStatus programStatus;
+
+    /**
+     * Indicates whether tracked entity instance is marked for follow up for the
+     * specified program.
+     */
+    private Boolean followUp;
+
+    /**
+     * Start date for enrollment in the given program.
+     */
+    private Date programStartDate;
+
+    /**
+     * End date for enrollment in the given program.
+     */
+    private Date programEndDate;
+
+    /**
+     * Tracked entity of the instances in the response.
+     */
+    private TrackedEntity trackedEntity;
+
+    /**
+     * Tracked entity instance.
+     */
+    private TrackedEntityInstance trackedEntityInstance;
+
+    /**
+     * Page number.
+     */
+    private Integer page;
+
+    /**
+     * Page size.
+     */
+    private Integer pageSize;
+
+    /**
+     * Indicates whether to include the total number of pages in the paging response.
+     */
+    private boolean totalPages;
+
+    /**
+     * Indicates whether paging should be skipped.
+     */
+    private boolean skipPaging;
+
+    // -------------------------------------------------------------------------
+    // Constructors
+    // -------------------------------------------------------------------------
+
+    public ProgramInstanceQueryParams()
+    {
+    }
+
+    // -------------------------------------------------------------------------
+    // Logic
+    // -------------------------------------------------------------------------
+
+    /**
+     * Adds an organisation unit to the parameters.
+     */
+    public void addOrganisationUnit( OrganisationUnit unit )
+    {
+        this.organisationUnits.add( unit );
+    }
+
+    /**
+     * Indicates whether this params specifies last updated.
+     */
+    public boolean hasLastUpdated()
+    {
+        return lastUpdated != null;
+    }
+
+    /**
+     * Indicates whether this params specifies any organisation units.
+     */
+    public boolean hasOrganisationUnits()
+    {
+        return organisationUnits != null && !organisationUnits.isEmpty();
+    }
+
+    /**
+     * Indicates whether this params specifies a program.
+     */
+    public boolean hasProgram()
+    {
+        return program != null;
+    }
+
+    /**
+     * Indicates whether this params specifies a program status.
+     */
+    public boolean hasProgramStatus()
+    {
+        return programStatus != null;
+    }
+
+    /**
+     * Indicates whether this params specifies follow up for the given program.
+     * Follow up can be specified as true or false.
+     */
+    public boolean hasFollowUp()
+    {
+        return followUp != null;
+    }
+
+    /**
+     * Indicates whether this params specifies a program start date.
+     */
+    public boolean hasProgramStartDate()
+    {
+        return programStartDate != null;
+    }
+
+    /**
+     * Indicates whether this params specifies a program end date.
+     */
+    public boolean hasProgramEndDate()
+    {
+        return programEndDate != null;
+    }
+
+    /**
+     * Indicates whether this params specifies a tracked entity.
+     */
+    public boolean hasTrackedEntity()
+    {
+        return trackedEntity != null;
+    }
+
+    /**
+     * Indicates whether this params specifies a tracked entity instance.
+     */
+    public boolean hasTrackedEntityInstance()
+    {
+        return trackedEntityInstance != null;
+    }
+
+    /**
+     * Indicates whether this params is of the given organisation unit mode.
+     */
+    public boolean isOrganisationUnitMode( OrganisationUnitSelectionMode mode )
+    {
+        return organisationUnitMode != null && organisationUnitMode.equals( mode );
+    }
+
+    /**
+     * Indicates whether paging is enabled.
+     */
+    public boolean isPaging()
+    {
+        return page != null || pageSize != null;
+    }
+
+    /**
+     * Returns the page number, falls back to default value of 1 if not specified.
+     */
+    public int getPageWithDefault()
+    {
+        return page != null && page > 0 ? page : DEFAULT_PAGE;
+    }
+
+    /**
+     * Returns the page size, falls back to default value of 50 if not specified.
+     */
+    public int getPageSizeWithDefault()
+    {
+        return pageSize != null && pageSize >= 0 ? pageSize : DEFAULT_PAGE_SIZE;
+    }
+
+    /**
+     * Returns the offset based on the page number and page size.
+     */
+    public int getOffset()
+    {
+        return (getPageWithDefault() - 1) * getPageSizeWithDefault();
+    }
+
+    /**
+     * Sets paging properties to default values.
+     */
+    public void setDefaultPaging()
+    {
+        this.page = DEFAULT_PAGE;
+        this.pageSize = DEFAULT_PAGE_SIZE;
+        this.skipPaging = false;
+    }
+
+    // -------------------------------------------------------------------------
+    // Getters and setters
+    // -------------------------------------------------------------------------
+
+    public Date getLastUpdated()
+    {
+        return lastUpdated;
+    }
+
+    public void setLastUpdated( Date lastUpdated )
+    {
+        this.lastUpdated = lastUpdated;
+    }
+
+    public Set<OrganisationUnit> getOrganisationUnits()
+    {
+        return organisationUnits;
+    }
+
+    public void setOrganisationUnits( Set<OrganisationUnit> organisationUnits )
+    {
+        this.organisationUnits = organisationUnits;
+    }
+
+    public OrganisationUnitSelectionMode getOrganisationUnitMode()
+    {
+        return organisationUnitMode;
+    }
+
+    public void setOrganisationUnitMode( OrganisationUnitSelectionMode organisationUnitMode )
+    {
+        this.organisationUnitMode = organisationUnitMode;
+    }
+
+    public Program getProgram()
+    {
+        return program;
+    }
+
+    public void setProgram( Program program )
+    {
+        this.program = program;
+    }
+
+    public ProgramStatus getProgramStatus()
+    {
+        return programStatus;
+    }
+
+    public void setProgramStatus( ProgramStatus programStatus )
+    {
+        this.programStatus = programStatus;
+    }
+
+    public Boolean getFollowUp()
+    {
+        return followUp;
+    }
+
+    public void setFollowUp( Boolean followUp )
+    {
+        this.followUp = followUp;
+    }
+
+    public Date getProgramStartDate()
+    {
+        return programStartDate;
+    }
+
+    public void setProgramStartDate( Date programStartDate )
+    {
+        this.programStartDate = programStartDate;
+    }
+
+    public Date getProgramEndDate()
+    {
+        return programEndDate;
+    }
+
+    public void setProgramEndDate( Date programEndDate )
+    {
+        this.programEndDate = programEndDate;
+    }
+
+    public TrackedEntity getTrackedEntity()
+    {
+        return trackedEntity;
+    }
+
+    public void setTrackedEntity( TrackedEntity trackedEntity )
+    {
+        this.trackedEntity = trackedEntity;
+    }
+
+    public TrackedEntityInstance getTrackedEntityInstance()
+    {
+        return trackedEntityInstance;
+    }
+
+    public void setTrackedEntityInstance( TrackedEntityInstance trackedEntityInstance )
+    {
+        this.trackedEntityInstance = trackedEntityInstance;
+    }
+
+    public Integer getPage()
+    {
+        return page;
+    }
+
+    public void setPage( Integer page )
+    {
+        this.page = page;
+    }
+
+    public Integer getPageSize()
+    {
+        return pageSize;
+    }
+
+    public void setPageSize( Integer pageSize )
+    {
+        this.pageSize = pageSize;
+    }
+
+    public boolean isTotalPages()
+    {
+        return totalPages;
+    }
+
+    public void setTotalPages( boolean totalPages )
+    {
+        this.totalPages = totalPages;
+    }
+
+    public boolean isSkipPaging()
+    {
+        return skipPaging;
+    }
+
+    public void setSkipPaging( boolean skipPaging )
+    {
+        this.skipPaging = skipPaging;
+    }
+}

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceService.java	2015-06-16 13:17:59 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceService.java	2015-07-07 06:11:54 +0000
@@ -29,6 +29,7 @@
  */
 
 import org.hisp.dhis.common.Grid;
+import org.hisp.dhis.common.OrganisationUnitSelectionMode;
 import org.hisp.dhis.i18n.I18n;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.trackedentity.TrackedEntityInstance;
@@ -36,6 +37,7 @@
 import java.util.Collection;
 import java.util.Date;
 import java.util.List;
+import java.util.Set;
 
 /**
  * @author Abyot Asalefew
@@ -83,6 +85,12 @@
      */
     ProgramInstance getProgramInstance( String uid );
 
+    ProgramInstanceQueryParams getFromUrl( Set<String> ou, OrganisationUnitSelectionMode ouMode, Date lastUpdated, String program,
+        ProgramStatus programStatus, Date programStartDate, Date programEndDate, String trackedEntity, String trackedEntityInstance,
+        Boolean followUp, Integer page, Integer pageSize, boolean totalPages, boolean skipPaging );
+
+    List<ProgramInstance> getProgramInstances( ProgramInstanceQueryParams params );
+
     /**
      * Retrieve program instances on a program
      *
@@ -287,7 +295,7 @@
     /**
      * Enroll a TrackedEntityInstance into a program. Must be run inside a transaction.
      *
-     * @param uid UID to use for new instance
+     * @param uid            UID to use for new instance
      * @param entityInstance TrackedEntityInstance
      * @param program        Program
      * @param enrollmentDate The date of enrollment

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceStore.java	2015-06-16 13:17:59 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceStore.java	2015-07-07 06:11:54 +0000
@@ -46,6 +46,14 @@
     String ID = ProgramInstanceStore.class.getName();
 
     /**
+     * Get all program instances by PI query params.
+     *
+     * @param params ProgramInstanceQueryParams to use
+     * @return PIs matching params
+     */
+    List<ProgramInstance> getProgramInstances( ProgramInstanceQueryParams params );
+
+    /**
      * Retrieve program instances on a program
      *
      * @param program Program

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/DefaultProgramInstanceService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/DefaultProgramInstanceService.java	2015-07-02 07:05:55 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/DefaultProgramInstanceService.java	2015-07-07 06:11:54 +0000
@@ -31,6 +31,8 @@
 import org.hisp.dhis.common.CodeGenerator;
 import org.hisp.dhis.common.Grid;
 import org.hisp.dhis.common.GridHeader;
+import org.hisp.dhis.common.IllegalQueryException;
+import org.hisp.dhis.common.OrganisationUnitSelectionMode;
 import org.hisp.dhis.dataelement.DataElement;
 import org.hisp.dhis.event.EventStatus;
 import org.hisp.dhis.i18n.I18n;
@@ -39,22 +41,27 @@
 import org.hisp.dhis.message.MessageConversation;
 import org.hisp.dhis.message.MessageService;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.period.PeriodType;
 import org.hisp.dhis.sms.SmsSender;
 import org.hisp.dhis.sms.SmsServiceException;
 import org.hisp.dhis.sms.outbound.OutboundSms;
 import org.hisp.dhis.system.grid.ListGrid;
+import org.hisp.dhis.trackedentity.TrackedEntity;
 import org.hisp.dhis.trackedentity.TrackedEntityAttribute;
 import org.hisp.dhis.trackedentity.TrackedEntityInstance;
 import org.hisp.dhis.trackedentity.TrackedEntityInstanceReminder;
 import org.hisp.dhis.trackedentity.TrackedEntityInstanceReminderService;
 import org.hisp.dhis.trackedentity.TrackedEntityInstanceService;
+import org.hisp.dhis.trackedentity.TrackedEntityService;
 import org.hisp.dhis.trackedentityattributevalue.TrackedEntityAttributeValue;
 import org.hisp.dhis.trackedentityattributevalue.TrackedEntityAttributeValueService;
 import org.hisp.dhis.trackedentitycomment.TrackedEntityComment;
 import org.hisp.dhis.trackedentitydatavalue.TrackedEntityDataValue;
 import org.hisp.dhis.trackedentitydatavalue.TrackedEntityDataValueService;
 import org.hisp.dhis.user.CurrentUserService;
+import org.hisp.dhis.user.User;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.ArrayList;
@@ -147,6 +154,12 @@
         this.trackedEntityInstanceService = trackedEntityInstanceService;
     }
 
+    @Autowired
+    private OrganisationUnitService organisationUnitService;
+
+    @Autowired
+    private TrackedEntityService trackedEntityService;
+
     private I18nManager i18nManager;
 
     public void setI18nManager( I18nManager i18nManager )
@@ -189,6 +202,93 @@
     }
 
     @Override
+    public ProgramInstanceQueryParams getFromUrl( Set<String> ou, OrganisationUnitSelectionMode ouMode, Date lastUpdated, String program, ProgramStatus programStatus,
+        Date programStartDate, Date programEndDate, String trackedEntity, String trackedEntityInstance, Boolean followUp, Integer page, Integer pageSize, boolean totalPages, boolean skipPaging )
+    {
+        ProgramInstanceQueryParams params = new ProgramInstanceQueryParams();
+
+        if ( ou != null )
+        {
+            for ( String orgUnit : ou )
+            {
+                OrganisationUnit organisationUnit = organisationUnitService.getOrganisationUnit( orgUnit );
+
+                if ( organisationUnit == null )
+                {
+                    throw new IllegalQueryException( "Organisation unit does not exist: " + orgUnit );
+                }
+
+                params.getOrganisationUnits().add( organisationUnit );
+            }
+        }
+
+        Program pr = program != null ? programService.getProgram( program ) : null;
+
+        if ( program != null && pr == null )
+        {
+            throw new IllegalQueryException( "Program does not exist: " + program );
+        }
+
+        TrackedEntity te = trackedEntity != null ? trackedEntityService.getTrackedEntity( trackedEntity ) : null;
+
+        if ( trackedEntity != null && te == null )
+        {
+            throw new IllegalQueryException( "Tracked entity does not exist: " + program );
+        }
+
+        TrackedEntityInstance tei = trackedEntityInstance != null ? trackedEntityInstanceService.getTrackedEntityInstance( trackedEntityInstance ) : null;
+
+        if ( trackedEntityInstance != null && tei == null )
+        {
+            throw new IllegalQueryException( "Tracked entity instance does not exist: " + program );
+        }
+
+        params.setProgram( pr );
+        params.setProgramStatus( programStatus );
+        params.setFollowUp( followUp );
+        params.setLastUpdated( lastUpdated );
+        params.setProgramStartDate( programStartDate );
+        params.setProgramEndDate( programEndDate );
+        params.setTrackedEntity( te );
+        params.setTrackedEntityInstance( tei );
+        params.setOrganisationUnitMode( ouMode );
+        params.setPage( page );
+        params.setPageSize( pageSize );
+        params.setTotalPages( totalPages );
+        params.setSkipPaging( skipPaging );
+
+        return params;
+    }
+
+    // TODO consider security
+    @Override
+    public List<ProgramInstance> getProgramInstances( ProgramInstanceQueryParams params )
+    {
+        User user = currentUserService.getCurrentUser();
+
+        if ( user != null && params.isOrganisationUnitMode( OrganisationUnitSelectionMode.ACCESSIBLE ) )
+        {
+            params.setOrganisationUnits( user.getDataViewOrganisationUnitsWithFallback() );
+            params.setOrganisationUnitMode( OrganisationUnitSelectionMode.DESCENDANTS );
+        }
+
+        for ( OrganisationUnit organisationUnit : params.getOrganisationUnits() )
+        {
+            if ( !organisationUnit.hasLevel() )
+            {
+                organisationUnit.setLevel( organisationUnitService.getLevelOfOrganisationUnit( organisationUnit.getId() ) );
+            }
+        }
+
+        if ( !params.isPaging() && !params.isSkipPaging() )
+        {
+            params.setDefaultPaging();
+        }
+
+        return programInstanceStore.getProgramInstances( params );
+    }
+
+    @Override
     public List<ProgramInstance> getProgramInstances( Program program )
     {
         return programInstanceStore.get( program );
@@ -794,7 +894,7 @@
                 && rm.getWhenToSend() != null
                 && rm.getWhenToSend() == status
                 && (rm.getMessageType() == TrackedEntityInstanceReminder.MESSAGE_TYPE_DHIS_MESSAGE || rm
-                    .getMessageType() == TrackedEntityInstanceReminder.MESSAGE_TYPE_BOTH) )
+                .getMessageType() == TrackedEntityInstanceReminder.MESSAGE_TYPE_BOTH) )
             {
                 int id = messageService.sendMessage( programInstance.getProgram().getDisplayName(),
                     reminderService.getMessageFromTemplate( rm, programInstance, format ), null,

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/hibernate/HibernateProgramInstanceStore.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/hibernate/HibernateProgramInstanceStore.java	2015-06-23 15:59:19 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/hibernate/HibernateProgramInstanceStore.java	2015-07-07 06:11:54 +0000
@@ -29,16 +29,20 @@
  */
 
 import org.hibernate.Criteria;
+import org.hibernate.Query;
 import org.hibernate.criterion.Order;
 import org.hibernate.criterion.Projections;
 import org.hibernate.criterion.Restrictions;
 import org.hisp.dhis.common.hibernate.HibernateIdentifiableObjectStore;
+import org.hisp.dhis.commons.util.SqlHelper;
+import org.hisp.dhis.commons.util.TextUtils;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.program.Program;
 import org.hisp.dhis.program.ProgramInstance;
+import org.hisp.dhis.program.ProgramInstanceQueryParams;
 import org.hisp.dhis.program.ProgramInstanceStore;
+import org.hisp.dhis.program.ProgramStatus;
 import org.hisp.dhis.program.SchedulingProgramObject;
-import org.hisp.dhis.commons.util.TextUtils;
 import org.hisp.dhis.trackedentity.TrackedEntityInstance;
 import org.hisp.dhis.trackedentity.TrackedEntityInstanceReminder;
 import org.hisp.dhis.trackedentity.TrackedEntityInstanceReminderService;
@@ -48,8 +52,14 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
+
+import static org.hisp.dhis.common.IdentifiableObjectUtils.getUids;
+import static org.hisp.dhis.commons.util.TextUtils.getQuotedCommaDelimitedString;
+import static org.hisp.dhis.system.util.DateUtils.getMediumDateString;
 
 /**
  * @author Abyot Asalefew
@@ -61,19 +71,98 @@
     @Autowired
     private TrackedEntityInstanceReminderService reminderService;
 
+    private static final Map<ProgramStatus, Integer> PROGRAM_STATUS_MAP = new HashMap<ProgramStatus, Integer>()
+    {
+        {
+            put( ProgramStatus.ACTIVE, ProgramInstance.STATUS_ACTIVE );
+            put( ProgramStatus.COMPLETED, ProgramInstance.STATUS_COMPLETED );
+            put( ProgramStatus.CANCELLED, ProgramInstance.STATUS_CANCELLED );
+        }
+    };
+
     // -------------------------------------------------------------------------
     // Implemented methods
     // -------------------------------------------------------------------------
 
     @Override
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings( "unchecked" )
+    public List<ProgramInstance> getProgramInstances( ProgramInstanceQueryParams params )
+    {
+        String hql = buildProgramInstanceHql( params );
+        Query query = getQuery( hql );
+
+        if ( params.isPaging() )
+        {
+            query.setFirstResult( params.getOffset() );
+            query.setMaxResults( params.getPageSizeWithDefault() );
+        }
+
+        return query.list();
+    }
+
+    private String buildProgramInstanceHql( ProgramInstanceQueryParams params )
+    {
+        SqlHelper hlp = new SqlHelper( true );
+
+        String hql = "from ProgramInstance pi";
+
+        if ( params.hasLastUpdated() )
+        {
+            hql += hlp.whereAnd() + "pi.lastUpdated >= '" + getMediumDateString( params.getLastUpdated() ) + "'";
+        }
+
+        if ( params.hasTrackedEntityInstance() )
+        {
+            hql += hlp.whereAnd() + "pi.entityInstance.uid = '" + params.getTrackedEntityInstance().getUid() + "'";
+        }
+
+        if ( params.hasTrackedEntity() )
+        {
+            hql += hlp.whereAnd() + "pi.entityInstance.trackedEntity.uid = '" + params.getTrackedEntity().getUid() + "'";
+        }
+
+        if ( params.hasOrganisationUnits() )
+        {
+            hql += hlp.whereAnd() + "pi.organisationUnit.uid in (" + getQuotedCommaDelimitedString( getUids( params.getOrganisationUnits() ) ) + ")";
+        }
+
+        if ( params.hasProgram() )
+        {
+            hql += hlp.whereAnd() + "pi.program.uid = '" + params.getProgram().getUid() + "'";
+        }
+
+        if ( params.hasProgramStatus() )
+        {
+            hql += hlp.whereAnd() + "pi.status = " + PROGRAM_STATUS_MAP.get( params.getProgramStatus() );
+        }
+
+        if ( params.hasFollowUp() )
+        {
+            hql += hlp.whereAnd() + "pi.followup = " + params.getFollowUp();
+        }
+
+        if ( params.hasProgramStartDate() )
+        {
+            hql += hlp.whereAnd() + "pi.enrollmentDate >= '" + getMediumDateString( params.getProgramStartDate() ) + "'";
+        }
+
+        if ( params.hasProgramEndDate() )
+        {
+            hql += hlp.whereAnd() + "pi.enrollmentDate <= '" + getMediumDateString( params.getProgramEndDate() ) + "'";
+        }
+
+        return hql;
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
     public List<ProgramInstance> get( Program program )
     {
         return getCriteria( Restrictions.eq( "program", program ) ).list();
     }
 
     @Override
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings( "unchecked" )
     public List<ProgramInstance> get( Collection<Program> programs )
     {
         if ( programs == null || programs.isEmpty() )
@@ -85,7 +174,7 @@
     }
 
     @Override
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings( "unchecked" )
     public List<ProgramInstance> get( Collection<Program> programs, OrganisationUnit organisationUnit )
     {
         if ( programs == null || programs.isEmpty() )
@@ -100,7 +189,7 @@
     }
 
     @Override
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings( "unchecked" )
     public List<ProgramInstance> get( Collection<Program> programs, OrganisationUnit organisationUnit, int status )
     {
         if ( programs == null || programs.isEmpty() )
@@ -116,14 +205,14 @@
     }
 
     @Override
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings( "unchecked" )
     public List<ProgramInstance> get( Program program, Integer status )
     {
         return getCriteria( Restrictions.eq( "program", program ), Restrictions.eq( "status", status ) ).list();
     }
 
     @Override
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings( "unchecked" )
     public List<ProgramInstance> get( Collection<Program> programs, Integer status )
     {
         if ( programs == null || programs.isEmpty() )
@@ -135,21 +224,21 @@
     }
 
     @Override
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings( "unchecked" )
     public List<ProgramInstance> get( TrackedEntityInstance entityInstance, Integer status )
     {
         return getCriteria( Restrictions.eq( "entityInstance", entityInstance ), Restrictions.eq( "status", status ) ).list();
     }
 
     @Override
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings( "unchecked" )
     public List<ProgramInstance> get( TrackedEntityInstance entityInstance, Program program )
     {
         return getCriteria( Restrictions.eq( "entityInstance", entityInstance ), Restrictions.eq( "program", program ) ).list();
     }
 
     @Override
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings( "unchecked" )
     public List<ProgramInstance> get( TrackedEntityInstance entityInstance, Program program, Integer status )
     {
         return getCriteria( Restrictions.eq( "entityInstance", entityInstance ), Restrictions.eq( "program", program ),
@@ -157,7 +246,7 @@
     }
 
     @Override
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings( "unchecked" )
     public List<ProgramInstance> get( Program program, OrganisationUnit organisationUnit, Integer min, Integer max )
     {
         Criteria criteria = getCriteria(
@@ -180,7 +269,7 @@
     }
 
     @Override
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings( "unchecked" )
     public List<ProgramInstance> get( Program program, Collection<Integer> orgunitIds, Date startDate,
         Date endDate, Integer min, Integer max )
     {
@@ -259,7 +348,7 @@
     }
 
     @Override
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings( "unchecked" )
     public List<ProgramInstance> getByStatus( Integer status, Program program, Collection<Integer> orgunitIds,
         Date startDate, Date endDate, Integer min, Integer max )
     {
@@ -300,7 +389,7 @@
         SqlRowSet rs = jdbcTemplate.queryForRowSet( sql );
 
         Collection<SchedulingProgramObject> schedulingProgramObjects = new HashSet<>();
-        
+
         while ( rs.next() )
         {
             String message = rs.getString( "templatemessage" );
@@ -348,7 +437,7 @@
 
             schedulingProgramObjects.add( schedulingProgramObject );
         }
-        
+
         return schedulingProgramObjects;
     }
 

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/trackedentity/hibernate/HibernateTrackedEntityInstanceStore.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/trackedentity/hibernate/HibernateTrackedEntityInstanceStore.java	2015-07-07 03:14:28 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/trackedentity/hibernate/HibernateTrackedEntityInstanceStore.java	2015-07-07 06:11:54 +0000
@@ -200,8 +200,6 @@
             hql += ")";
         }
 
-        System.err.println( "hql: " + hql );
-
         return hql;
     }
 

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/enrollment/AbstractEnrollmentService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/enrollment/AbstractEnrollmentService.java	2015-07-03 07:33:54 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/enrollment/AbstractEnrollmentService.java	2015-07-07 06:11:54 +0000
@@ -30,13 +30,12 @@
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-
 import org.hisp.dhis.common.Grid;
 import org.hisp.dhis.common.IdentifiableObjectManager;
-import org.hisp.dhis.common.IdentifiableObjectUtils;
 import org.hisp.dhis.common.OrganisationUnitSelectionMode;
 import org.hisp.dhis.common.QueryItem;
 import org.hisp.dhis.common.QueryOperator;
+import org.hisp.dhis.commons.collection.CachingMap;
 import org.hisp.dhis.dbms.DbmsManager;
 import org.hisp.dhis.dxf2.events.event.Note;
 import org.hisp.dhis.dxf2.events.trackedentity.Attribute;
@@ -65,12 +64,10 @@
 import org.hisp.dhis.trackedentitycomment.TrackedEntityCommentService;
 import org.hisp.dhis.user.CurrentUserService;
 import org.hisp.dhis.user.UserService;
-import org.hisp.dhis.commons.collection.CachingMap;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.Assert;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Date;
 import java.util.HashSet;
@@ -159,14 +156,6 @@
     }
 
     @Override
-    public Enrollments getEnrollments( TrackedEntityInstance trackedEntityInstance, EnrollmentStatus status )
-    {
-        org.hisp.dhis.trackedentity.TrackedEntityInstance entityInstance = getTrackedEntityInstance( trackedEntityInstance
-            .getTrackedEntityInstance() );
-        return getEnrollments( entityInstance, status );
-    }
-
-    @Override
     public Enrollments getEnrollments( org.hisp.dhis.trackedentity.TrackedEntityInstance entityInstance )
     {
         List<ProgramInstance> programInstances = new ArrayList<>( entityInstance.getProgramInstances() );
@@ -185,89 +174,6 @@
     }
 
     @Override
-    public Enrollments getEnrollments( Program program )
-    {
-        List<ProgramInstance> programInstances = new ArrayList<>(
-            programInstanceService.getProgramInstances( program ) );
-        return getEnrollments( programInstances );
-    }
-
-    @Override
-    public Enrollments getEnrollments( Program program, EnrollmentStatus status )
-    {
-        List<ProgramInstance> programInstances = new ArrayList<>(
-            programInstanceService.getProgramInstances( program, status.getValue() ) );
-
-        return getEnrollments( programInstances );
-    }
-
-    @Override
-    public Enrollments getEnrollments( Program program, EnrollmentStatus status, OrganisationUnit organisationUnit, Date startDate, Date endDate )
-    {
-        List<ProgramInstance> programInstances = new ArrayList<>(
-            programInstanceService.getProgramInstancesByStatus( status.getValue(), program, Arrays.asList( organisationUnit.getId() ), startDate, endDate ) );
-
-        return getEnrollments( programInstances );
-    }
-
-    @Override
-    public Enrollments getEnrollments( Program program, EnrollmentStatus status, List<OrganisationUnit> organisationUnits, Date startDate, Date endDate )
-    {
-        List<ProgramInstance> programInstances = new ArrayList<>(
-            programInstanceService.getProgramInstancesByStatus( status.getValue(), program, IdentifiableObjectUtils.getIdentifiers( organisationUnits ), startDate, endDate ) );
-
-        return getEnrollments( programInstances );
-    }
-
-    @Override
-    public Enrollments getEnrollments( OrganisationUnit organisationUnit )
-    {
-        List<Program> programs = getProgramsWithRegistration();
-        List<ProgramInstance> programInstances = new ArrayList<>(
-            programInstanceService.getProgramInstances( programs, organisationUnit ) );
-
-        return getEnrollments( programInstances );
-    }
-
-    @Override
-    public Enrollments getEnrollments( OrganisationUnit organisationUnit, EnrollmentStatus status )
-    {
-        List<Program> programs = getProgramsWithRegistration();
-        List<ProgramInstance> programInstances = new ArrayList<>(
-            programInstanceService.getProgramInstances( programs, organisationUnit, status.getValue() ) );
-
-        return getEnrollments( programInstances );
-    }
-
-    @Override
-    public Enrollments getEnrollments( Program program, OrganisationUnit organisationUnit )
-    {
-        return getEnrollments( programInstanceService.getProgramInstances( program, organisationUnit, 0, null ) );
-    }
-
-    @Override
-    public Enrollments getEnrollments( Program program, OrganisationUnit organisationUnit, Date startDate, Date endDate )
-    {
-        return getEnrollments(
-            programInstanceService.getProgramInstances( program, Arrays.asList( organisationUnit.getId() ), startDate, endDate, 0, Integer.MAX_VALUE ) );
-    }
-
-    @Override
-    public Enrollments getEnrollments( Program program, List<OrganisationUnit> organisationUnits, Date startDate, Date endDate )
-    {
-        return getEnrollments(
-            programInstanceService.getProgramInstances( program, IdentifiableObjectUtils.getIdentifiers( organisationUnits ), startDate, endDate, 0, Integer.MAX_VALUE ) );
-    }
-
-    @Override
-    public Enrollments getEnrollments( Program program, TrackedEntityInstance trackedEntityInstance )
-    {
-        org.hisp.dhis.trackedentity.TrackedEntityInstance entityInstance = getTrackedEntityInstance( trackedEntityInstance
-            .getTrackedEntityInstance() );
-        return getEnrollments( programInstanceService.getProgramInstances( entityInstance, program ) );
-    }
-
-    @Override
     public Enrollments getEnrollments( Program program, TrackedEntityInstance trackedEntityInstance,
         EnrollmentStatus status )
     {
@@ -309,6 +215,7 @@
 
         if ( programInstance.getEntityInstance() != null )
         {
+            enrollment.setTrackedEntity( programInstance.getEntityInstance().getTrackedEntity().getUid() );
             enrollment.setTrackedEntityInstance( programInstance.getEntityInstance().getUid() );
         }
 
@@ -317,6 +224,8 @@
             enrollment.setOrgUnit( programInstance.getOrganisationUnit().getUid() );
         }
 
+        enrollment.setCreated( programInstance.getCreated() );
+        enrollment.setLastUpdated( programInstance.getLastUpdated() );
         enrollment.setProgram( programInstance.getProgram().getUid() );
         enrollment.setStatus( EnrollmentStatus.fromInt( programInstance.getStatus() ) );
         enrollment.setDateOfEnrollment( programInstance.getEnrollmentDate() );

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/enrollment/Enrollment.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/enrollment/Enrollment.java	2015-07-07 03:54:38 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/enrollment/Enrollment.java	2015-07-07 06:11:54 +0000
@@ -29,13 +29,9 @@
  */
 
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonView;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
-
 import org.hisp.dhis.common.DxfNamespaces;
-import org.hisp.dhis.common.view.DetailedView;
-import org.hisp.dhis.common.view.ExportView;
 import org.hisp.dhis.dxf2.events.event.Note;
 import org.hisp.dhis.dxf2.events.trackedentity.Attribute;
 
@@ -51,6 +47,12 @@
 {
     private String enrollment;
 
+    private Date created;
+
+    private Date lastUpdated;
+
+    private String trackedEntity;
+
     private String trackedEntityInstance;
 
     private String program;
@@ -64,9 +66,9 @@
     private Date dateOfIncident;
 
     private List<Attribute> attributes = new ArrayList<>();
-    
+
     private List<Note> notes = new ArrayList<>();
-    
+
     private Boolean followup;
 
     public Enrollment()
@@ -87,6 +89,42 @@
 
     @JsonProperty( required = true )
     @JacksonXmlProperty( isAttribute = true )
+    public Date getCreated()
+    {
+        return created;
+    }
+
+    public void setCreated( Date created )
+    {
+        this.created = created;
+    }
+
+    @JsonProperty( required = true )
+    @JacksonXmlProperty( isAttribute = true )
+    public Date getLastUpdated()
+    {
+        return lastUpdated;
+    }
+
+    public void setLastUpdated( Date lastUpdated )
+    {
+        this.lastUpdated = lastUpdated;
+    }
+
+    @JsonProperty( required = true )
+    @JacksonXmlProperty( isAttribute = true )
+    public String getTrackedEntity()
+    {
+        return trackedEntity;
+    }
+
+    public void setTrackedEntity( String trackedEntity )
+    {
+        this.trackedEntity = trackedEntity;
+    }
+
+    @JsonProperty( required = true )
+    @JacksonXmlProperty( isAttribute = true )
     public String getTrackedEntityInstance()
     {
         return trackedEntityInstance;
@@ -168,7 +206,7 @@
     {
         this.attributes = attributes;
     }
-    
+
     @JsonProperty
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 )
     public List<Note> getNotes()
@@ -180,9 +218,9 @@
     {
         this.notes = notes;
     }
-    
+
     @JsonProperty
-    @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
+    @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 )
     public Boolean getFollowup()
     {
         return followup;

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/enrollment/EnrollmentService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/enrollment/EnrollmentService.java	2015-06-08 03:34:10 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/enrollment/EnrollmentService.java	2015-07-07 06:11:54 +0000
@@ -59,34 +59,12 @@
 
     Enrollments getEnrollments( TrackedEntityInstance trackedEntityInstance );
 
-    Enrollments getEnrollments( TrackedEntityInstance trackedEntityInstance, EnrollmentStatus status );
-
     Enrollments getEnrollments( org.hisp.dhis.trackedentity.TrackedEntityInstance entityInstance );
 
     Enrollments getEnrollments( org.hisp.dhis.trackedentity.TrackedEntityInstance entityInstance, EnrollmentStatus status );
 
-    Enrollments getEnrollments( Program program );
-
-    Enrollments getEnrollments( Program program, EnrollmentStatus status );
-
-    Enrollments getEnrollments( Program program, EnrollmentStatus status, OrganisationUnit organisationUnit, Date startDate, Date endDate );
-
-    Enrollments getEnrollments( Program program, EnrollmentStatus status, List<OrganisationUnit> organisationUnits, Date startDate, Date endDate );
-
-    Enrollments getEnrollments( Program program, TrackedEntityInstance trackedEntityInstance );
-
     Enrollments getEnrollments( Program program, TrackedEntityInstance trackedEntityInstance, EnrollmentStatus status );
 
-    Enrollments getEnrollments( OrganisationUnit organisationUnit );
-
-    Enrollments getEnrollments( OrganisationUnit organisationUnit, EnrollmentStatus status );
-
-    Enrollments getEnrollments( Program program, OrganisationUnit organisationUnit );
-
-    Enrollments getEnrollments( Program program, OrganisationUnit organisationUnit, Date startDate, Date endDate );
-
-    Enrollments getEnrollments( Program program, List<OrganisationUnit> organisationUnits, Date startDate, Date endDate );
-
     Enrollments getEnrollments( Collection<ProgramInstance> programInstances );
 
     Enrollment getEnrollment( String id );

=== modified file 'dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/util/SqlHelper.java'
--- dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/util/SqlHelper.java	2015-06-15 13:44:20 +0000
+++ dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/util/SqlHelper.java	2015-07-07 06:11:54 +0000
@@ -34,16 +34,27 @@
 public class SqlHelper
 {
     private boolean whereAndInvoked = false;
-    
+
+    private boolean includeSpaces = false;
+
+    public SqlHelper()
+    {
+    }
+
+    public SqlHelper( boolean includeSpaces )
+    {
+        this.includeSpaces = includeSpaces;
+    }
+
     /**
      * Returns "where" the first time it is invoked, then "and" for subsequent invocations.
      */
     public String whereAnd()
     {
         String str = whereAndInvoked ? "and" : "where";
-        
+
         whereAndInvoked = true;
-        
-        return str;
+
+        return includeSpaces ? " " + str + " " : str;
     }
 }

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EnrollmentController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EnrollmentController.java	2015-07-07 04:02:54 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EnrollmentController.java	2015-07-07 06:11:54 +0000
@@ -29,15 +29,11 @@
  */
 
 import com.google.common.collect.Lists;
-import org.hisp.dhis.common.IdentifiableObjectManager;
 import org.hisp.dhis.common.OrganisationUnitSelectionMode;
 import org.hisp.dhis.dxf2.common.JacksonUtils;
 import org.hisp.dhis.dxf2.events.enrollment.Enrollment;
 import org.hisp.dhis.dxf2.events.enrollment.EnrollmentService;
 import org.hisp.dhis.dxf2.events.enrollment.EnrollmentStatus;
-import org.hisp.dhis.dxf2.events.enrollment.Enrollments;
-import org.hisp.dhis.dxf2.events.trackedentity.TrackedEntityInstance;
-import org.hisp.dhis.dxf2.events.trackedentity.TrackedEntityInstanceService;
 import org.hisp.dhis.dxf2.fieldfilter.FieldFilterService;
 import org.hisp.dhis.dxf2.importsummary.ImportStatus;
 import org.hisp.dhis.dxf2.importsummary.ImportSummaries;
@@ -45,9 +41,9 @@
 import org.hisp.dhis.importexport.ImportStrategy;
 import org.hisp.dhis.node.NodeUtils;
 import org.hisp.dhis.node.types.RootNode;
-import org.hisp.dhis.organisationunit.OrganisationUnit;
-import org.hisp.dhis.organisationunit.OrganisationUnitService;
-import org.hisp.dhis.program.Program;
+import org.hisp.dhis.program.ProgramInstanceQueryParams;
+import org.hisp.dhis.program.ProgramInstanceService;
+import org.hisp.dhis.program.ProgramStatus;
 import org.hisp.dhis.webapi.controller.exception.NotFoundException;
 import org.hisp.dhis.webapi.service.ContextService;
 import org.hisp.dhis.webapi.utils.ContextUtils;
@@ -72,6 +68,7 @@
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
@@ -86,13 +83,7 @@
     private EnrollmentService enrollmentService;
 
     @Autowired
-    private TrackedEntityInstanceService trackedEntityInstanceService;
-
-    @Autowired
-    private IdentifiableObjectManager manager;
-
-    @Autowired
-    private OrganisationUnitService organisationUnitService;
+    private ProgramInstanceService programInstanceService;
 
     @Autowired
     protected FieldFilterService fieldFilterService;
@@ -106,71 +97,37 @@
 
     @RequestMapping( value = "", method = RequestMethod.GET )
     public @ResponseBody RootNode getEnrollments(
-        @RequestParam( value = "orgUnit", required = false ) String orgUnitUid,
-        @RequestParam( value = "program", required = false ) String programUid,
-        @RequestParam( value = "trackedEntityInstance", required = false ) String trackedEntityInstanceUid,
-        @RequestParam( required = false ) Date startDate,
-        @RequestParam( required = false ) Date endDate,
+        @RequestParam( required = false ) String ou,
         @RequestParam( required = false ) OrganisationUnitSelectionMode ouMode,
-        @RequestParam( value = "status", required = false ) EnrollmentStatus status ) throws NotFoundException
+        @RequestParam( required = false ) String program,
+        @RequestParam( required = false ) ProgramStatus programStatus,
+        @RequestParam( required = false ) Boolean followUp,
+        @RequestParam( required = false ) Date lastUpdated,
+        @RequestParam( required = false ) Date programStartDate,
+        @RequestParam( required = false ) Date programEndDate,
+        @RequestParam( required = false ) String trackedEntity,
+        @RequestParam( required = false ) String trackedEntityInstance,
+        @RequestParam( required = false ) Integer page,
+        @RequestParam( required = false ) Integer pageSize,
+        @RequestParam( required = false ) boolean totalPages,
+        @RequestParam( required = false ) boolean skipPaging )
     {
         List<String> fields = Lists.newArrayList( contextService.getParameterValues( "fields" ) );
-        Enrollments enrollments;
 
         if ( fields.isEmpty() )
         {
-            fields.add( "enrollment,trackedEntityInstance,program,status,orgUnit,dateOfEnrollment,dateOfIncident,followup" );
-        }
-
-        if ( startDate != null && endDate != null && programUid != null && orgUnitUid != null && ouMode != null )
-        {
-            OrganisationUnit organisationUnit = getOrganisationUnit( orgUnitUid );
-            List<OrganisationUnit> organisationUnits = getOrganisationUnits( organisationUnit, ouMode );
-
-            Program program = getProgram( programUid );
-
-            enrollments = status != null ?
-                enrollmentService.getEnrollments( program, status, organisationUnits, startDate, endDate ) :
-                enrollmentService.getEnrollments( program, organisationUnits, startDate, endDate );
-        }
-        else if ( orgUnitUid == null && programUid == null && trackedEntityInstanceUid == null )
-        {
-            enrollments = status != null ? enrollmentService.getEnrollments( status ) : enrollmentService.getEnrollments();
-        }
-        else if ( orgUnitUid != null && programUid != null )
-        {
-            OrganisationUnit organisationUnit = getOrganisationUnit( orgUnitUid );
-            Program program = getProgram( programUid );
-
-            enrollments = enrollmentService.getEnrollments( program, organisationUnit );
-        }
-        else if ( programUid != null && trackedEntityInstanceUid != null )
-        {
-            Program program = getProgram( programUid );
-            TrackedEntityInstance trackedEntityInstance = getTrackedEntityInstance( trackedEntityInstanceUid );
-
-            enrollments = status != null ? enrollmentService.getEnrollments( program, trackedEntityInstance, status )
-                : enrollmentService.getEnrollments( program, trackedEntityInstance );
-        }
-        else if ( orgUnitUid != null )
-        {
-            OrganisationUnit organisationUnit = getOrganisationUnit( orgUnitUid );
-            enrollments = status != null ? enrollmentService.getEnrollments( organisationUnit, status )
-                : enrollmentService.getEnrollments( organisationUnit );
-        }
-        else if ( programUid != null )
-        {
-            Program program = getProgram( programUid );
-            enrollments = status != null ? enrollmentService.getEnrollments( program, status ) : enrollmentService.getEnrollments( program );
-        }
-        else
-        {
-            TrackedEntityInstance trackedEntityInstance = getTrackedEntityInstance( trackedEntityInstanceUid );
-            enrollments = status != null ? enrollmentService.getEnrollments( trackedEntityInstance, status ) : enrollmentService.getEnrollments( trackedEntityInstance );
-        }
+            fields.add( "enrollment,created,lastUpdated,trackedEntity,trackedEntityInstance,program,status,orgUnit,dateOfEnrollment,dateOfIncident,followup" );
+        }
+
+        Set<String> orgUnits = ContextUtils.getQueryParamValues( ou );
+        ProgramInstanceQueryParams params = programInstanceService.getFromUrl( orgUnits, ouMode, lastUpdated, program, programStatus, programStartDate,
+            programEndDate, trackedEntity, trackedEntityInstance, followUp, page, pageSize, totalPages, skipPaging );
+
+        List<Enrollment> enrollments = new ArrayList<>( enrollmentService.getEnrollments(
+            programInstanceService.getProgramInstances( params ) ).getEnrollments() );
 
         RootNode rootNode = NodeUtils.createMetadata();
-        rootNode.addChild( fieldFilterService.filter( Enrollment.class, enrollments.getEnrollments(), fields ) );
+        rootNode.addChild( fieldFilterService.filter( Enrollment.class, enrollments, fields ) );
 
         return rootNode;
     }
@@ -318,63 +275,6 @@
         return enrollment;
     }
 
-    private TrackedEntityInstance getTrackedEntityInstance( String id ) throws NotFoundException
-    {
-        TrackedEntityInstance trackedEntityInstance = trackedEntityInstanceService.getTrackedEntityInstance( id );
-
-        if ( trackedEntityInstance == null )
-        {
-            throw new NotFoundException( "TrackedEntityInstance", id );
-        }
-
-        return trackedEntityInstance;
-    }
-
-    private OrganisationUnit getOrganisationUnit( String id ) throws NotFoundException
-    {
-        OrganisationUnit organisationUnit = manager.get( OrganisationUnit.class, id );
-
-        if ( organisationUnit == null )
-        {
-            throw new NotFoundException( "OrganisationUnit", id );
-        }
-
-        return organisationUnit;
-    }
-
-    private List<OrganisationUnit> getOrganisationUnits( OrganisationUnit rootOrganisationUnit, OrganisationUnitSelectionMode ouMode )
-    {
-        List<OrganisationUnit> organisationUnits = new ArrayList<>();
-
-        if ( OrganisationUnitSelectionMode.DESCENDANTS.equals( ouMode ) )
-        {
-            organisationUnits.addAll( organisationUnitService.getOrganisationUnitWithChildren( rootOrganisationUnit.getUid() ) );
-        }
-        else if ( OrganisationUnitSelectionMode.CHILDREN.equals( ouMode ) )
-        {
-            organisationUnits.add( rootOrganisationUnit );
-            organisationUnits.addAll( rootOrganisationUnit.getChildren() );
-        }
-        else // SELECTED
-        {
-            organisationUnits.add( rootOrganisationUnit );
-        }
-
-        return organisationUnits;
-    }
-
-    private Program getProgram( String id ) throws NotFoundException
-    {
-        Program program = manager.get( Program.class, id );
-
-        if ( program == null )
-        {
-            throw new NotFoundException( "Program", id );
-        }
-
-        return program;
-    }
-
     private String getResourcePath( HttpServletRequest request, ImportSummary importSummary )
     {
         return ContextUtils.getContextPath( request ) + "/api/" + "enrollments" + "/" + importSummary.getReference();