← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 9563: Add ad-hoc aggregated reports in Tabular reports (WIP).

 

------------------------------------------------------------
revno: 9563
committer: Tran Chau <tran.hispvietnam@xxxxxxxxx>
branch nick: dhis2
timestamp: Mon 2013-01-21 13:18:31 +0700
message:
  Add ad-hoc aggregated reports in Tabular reports (WIP).
added:
  dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/report/GetOrganisationUnitsByGroupAction.java
  dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/jsonminOrganisationUnitPaths.vm
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageInstanceService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageInstanceStore.java
  dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/DefaultProgramStageInstanceService.java
  dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/hibernate/HibernateProgramStageInstanceStore.java
  dhis-2/dhis-services/dhis-service-patient/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/report/GenerateAggregateReportAction.java
  dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/report/GetOrganisationUnitChildrenAction.java
  dhis-2/dhis-web/dhis-web-caseentry/src/main/resources/META-INF/dhis/beans.xml
  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/struts.xml
  dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/app/app.js
  dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/i18n.vm
  dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/jsonTabularAggregateReport.vm
  dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/jsonTabularInitialize.vm
  dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/jsonminOrganisationUnitChildren.vm


--
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/program/ProgramStageInstanceService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageInstanceService.java	2013-01-17 07:31:43 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageInstanceService.java	2013-01-21 06:18:31 +0000
@@ -111,8 +111,7 @@
         Collection<Integer> orgunitIds, Date startDate, Date endDate, int status, Integer max, Integer min );
 
     Grid getAggregateReport( int position, ProgramStage programStage, Collection<Integer> orgunitIds,
-        Integer dataElementId, Map<Integer, String> deFilters, Collection<Period> periods, String aggregateType,
-        Integer limit, Boolean useCompletedEvents, I18nFormat format,
-        I18n i18n );
+        String facilityLB, Integer dataElementId, Map<Integer, String> deFilters, Collection<Period> periods,
+        String aggregateType, Integer limit, Boolean useCompletedEvents, I18nFormat format, I18n i18n );
 
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageInstanceStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageInstanceStore.java	2013-01-17 07:31:43 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageInstanceStore.java	2013-01-21 06:18:31 +0000
@@ -102,7 +102,7 @@
         Collection<Integer> orgunitIds, Date startDate, Date endDate, int status, Integer min, Integer max );
 
     Grid getAggregateReport( int position, ProgramStage programStage, Collection<Integer> orgunitIds,
-        Integer dataElementId, Map<Integer, String> deFilters, Collection<Period> periods, String aggregateType,
-        Integer limit, Boolean useCompletedEvents, I18nFormat format, I18n i18n );
+        String facilityLB, Integer dataElementId, Map<Integer, String> deFilters, Collection<Period> periods,
+        String aggregateType, Integer limit, Boolean useCompletedEvents, I18nFormat format, I18n i18n );
 
 }

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/DefaultProgramStageInstanceService.java'
--- dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/DefaultProgramStageInstanceService.java	2013-01-17 07:31:43 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/DefaultProgramStageInstanceService.java	2013-01-21 06:18:31 +0000
@@ -347,11 +347,11 @@
 
     @Override
     public Grid getAggregateReport( int position, ProgramStage programStage, Collection<Integer> orgunitIds,
-        Integer dataElementId, Map<Integer, String> deFilters, Collection<Period> periods, String aggregateType,
-        Integer limit, Boolean useCompletedEvents, I18nFormat format, I18n i18n )
+        String facilityLB, Integer dataElementId, Map<Integer, String> deFilters, Collection<Period> periods,
+        String aggregateType, Integer limit, Boolean useCompletedEvents, I18nFormat format, I18n i18n )
     {
-        return programStageInstanceStore.getAggregateReport( position, programStage, orgunitIds, dataElementId, deFilters, periods,
-            aggregateType, limit, useCompletedEvents, format, i18n );
+        return programStageInstanceStore.getAggregateReport( position, programStage, orgunitIds, facilityLB,
+            dataElementId, deFilters, periods, aggregateType, limit, useCompletedEvents, format, i18n );
     }
 
 }

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/hibernate/HibernateProgramStageInstanceStore.java'
--- dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/hibernate/HibernateProgramStageInstanceStore.java	2013-01-17 08:06:51 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/hibernate/HibernateProgramStageInstanceStore.java	2013-01-21 06:18:31 +0000
@@ -43,7 +43,6 @@
 import org.hibernate.criterion.Restrictions;
 import org.hisp.dhis.common.Grid;
 import org.hisp.dhis.common.GridHeader;
-import org.hisp.dhis.dataelement.DataElement;
 import org.hisp.dhis.dataelement.DataElementService;
 import org.hisp.dhis.hibernate.HibernateGenericStore;
 import org.hisp.dhis.i18n.I18n;
@@ -51,6 +50,7 @@
 import org.hisp.dhis.jdbc.StatementBuilder;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.organisationunit.OrganisationUnitLevel;
+import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.patient.Patient;
 import org.hisp.dhis.patientreport.PatientAggregateReport;
 import org.hisp.dhis.patientreport.TabularReportColumn;
@@ -100,6 +100,13 @@
         this.dataElementService = dataElementService;
     }
 
+    private OrganisationUnitService organisationUnitService;
+
+    public void setOrganisationUnitService( OrganisationUnitService organisationUnitService )
+    {
+        this.organisationUnitService = organisationUnitService;
+    }
+
     // -------------------------------------------------------------------------
     // Implemented methods
     // -------------------------------------------------------------------------
@@ -385,8 +392,8 @@
     }
 
     public Grid getAggregateReport( int position, ProgramStage programStage, Collection<Integer> orgunitIds,
-        Integer dataElementId, Map<Integer, String> deFilters, Collection<Period> periods, String aggregateType,
-        Integer limit, Boolean useCompletedEvents, I18nFormat format, I18n i18n )
+        String facilityLB, Integer deGroupBy, Map<Integer, String> deFilters, Collection<Period> periods,
+        String aggregateType, Integer limit, Boolean useCompletedEvents, I18nFormat format, I18n i18n )
     {
         String sql = "";
         String filterSQL = filterSQLStatement( deFilters );
@@ -406,15 +413,26 @@
 
             for ( Period period : periods )
             {
-                grid.addHeader( new GridHeader( format.formatPeriod( period ), false, false ) );
+                String periodName = "";
+                if ( period.getPeriodType() != null )
+                {
+                    periodName = format.formatPeriod( period );
+                }
+                else
+                {
+                    String startDate = format.formatDate( period.getStartDate() );
+                    String endDate = format.formatDate( period.getEndDate() );
+                    periodName = startDate + " -> " + endDate;
+                }
+                grid.addHeader( new GridHeader( periodName, false, false ) );
             }
 
             // ---------------------------------------------------------------------
             // Get SQL and build grid
             // ---------------------------------------------------------------------
 
-            sql = getAggregateReportSQL12( programStage, orgunitIds, filterSQL, periods, aggregateType,
-                useCompletedEvents, format );
+            sql = getAggregateReportSQL12( programStage, orgunitIds, facilityLB, filterSQL, deGroupBy, periods,
+                aggregateType, useCompletedEvents, format );
         }
         // Type = 2
         if ( position == PatientAggregateReport.POSITION_ROW_PERIOD_COLUMN_ORGUNIT )
@@ -423,8 +441,8 @@
             // Get SQL and build grid
             // ---------------------------------------------------------------------
 
-            sql = getAggregateReportSQL12( programStage, orgunitIds, filterSQL, periods, aggregateType,
-                useCompletedEvents, format );
+            sql = getAggregateReportSQL12( programStage, orgunitIds, facilityLB, filterSQL, deGroupBy, periods,
+                aggregateType, useCompletedEvents, format );
 
         }
         // Type = 3
@@ -442,8 +460,8 @@
             // Get SQL and build grid
             // ---------------------------------------------------------------------
 
-            sql = getAggregateReportSQL34( position, programStage, orgunitIds, filterSQL, periods, aggregateType,
-                useCompletedEvents, format );
+            sql = getAggregateReportSQL3( position, programStage, orgunitIds, facilityLB, filterSQL, deGroupBy,
+                periods, aggregateType, useCompletedEvents, format );
 
         }
         // Type = 4
@@ -460,8 +478,8 @@
             // Get SQL and build grid
             // ---------------------------------------------------------------------
 
-            sql = getAggregateReportSQL34( position, programStage, orgunitIds, filterSQL, periods, aggregateType,
-                useCompletedEvents, format );
+            sql = getAggregateReportSQL4( position, programStage, orgunitIds, facilityLB, filterSQL, deGroupBy,
+                periods, aggregateType, useCompletedEvents, format );
 
         }
         // type = 5
@@ -480,116 +498,117 @@
 
             List<Period> firstPeriod = new ArrayList<Period>();
             firstPeriod.add( periods.iterator().next() );
-            sql = getAggregateReportSQL5( position, programStage, orgunitIds, filterSQL, periods.iterator().next(),
-                aggregateType, useCompletedEvents, format );
+            sql = getAggregateReportSQL5( position, programStage, orgunitIds, facilityLB, filterSQL, deGroupBy, periods
+                .iterator().next(), aggregateType, useCompletedEvents, format );
 
         }
+
         // Type = 6 && With group-by
-        else if ( position == PatientAggregateReport.POSITION_ROW_PERIOD_COLUMN_DATA && dataElementId != null )
+        else if ( position == PatientAggregateReport.POSITION_ROW_PERIOD_COLUMN_DATA && deGroupBy != null )
         {
             List<String> deValues = new ArrayList<String>();
 
-            deValues = dataElementService.getDataElement( dataElementId ).getOptionSet().getOptions();
-
-            // ---------------------------------------------------------------------
-            // Headers cols
-            // ---------------------------------------------------------------------
-
-            grid.addHeader( new GridHeader( i18n.getString( "period" ), false, true ) );
-
-            for ( String deValue : deValues )
-            {
-                grid.addHeader( new GridHeader( deValue, false, false ) );
-            }
-
-            // ---------------------------------------------------------------------
-            // Get SQL and build grid
-            // ---------------------------------------------------------------------
-
-            sql = getAggregateReportSQL6( programStage, orgunitIds, filterSQL, dataElementId, deValues, periods,
-                aggregateType, useCompletedEvents, format );
-        }
-
-        // Type = 6 && Without group-by
-
-        else if ( position == PatientAggregateReport.POSITION_ROW_PERIOD_COLUMN_DATA && dataElementId == null )
-        {
-            grid.addHeader( new GridHeader( i18n.getString( "period" ), false, true ) );
-
-            grid.addHeader( new GridHeader( i18n.getString( aggregateType ), false, false ) );
-
-            // ---------------------------------------------------------------------
-            // Get SQL and build grid
-            // ---------------------------------------------------------------------
-
-            sql = getAggregateReportSQL6NotGroupBy( programStage, orgunitIds, filterSQL, periods, aggregateType,
-                useCompletedEvents, format );
-        }
-
-        // Type = 7 && With group-by
-        else if ( position == PatientAggregateReport.POSITION_ROW_ORGUNIT_COLUMN_DATA && dataElementId != null )
-        {
-            List<String> deValues = dataElementService.getDataElement( dataElementId ).getOptionSet().getOptions();
-
-            // ---------------------------------------------------------------------
-            // Headers cols
-            // ---------------------------------------------------------------------
-
-            grid.addHeader( new GridHeader( i18n.getString( "orgunit" ), false, true ) );
-
-            for ( String deValue : deValues )
-            {
-                grid.addHeader( new GridHeader( deValue, false, false ) );
-            }
-
-            // ---------------------------------------------------------------------
-            // Get SQL and build grid
-            // ---------------------------------------------------------------------
-
-            sql = getAggregateReportSQL7( programStage, orgunitIds, filterSQL, dataElementId, deValues, periods
-                .iterator().next(), aggregateType, useCompletedEvents, format );
-
-        }
-
-        // Type = 7 && Without group-by
-        else if ( position == PatientAggregateReport.POSITION_ROW_ORGUNIT_COLUMN_DATA && dataElementId == null )
-        {
-            // ---------------------------------------------------------------------
-            // Headers cols
-            // ---------------------------------------------------------------------
-
-            grid.addHeader( new GridHeader( i18n.getString( "orgunit" ), false, true ) );
-
-            grid.addHeader( new GridHeader( i18n.getString( aggregateType ), false, true ) );
-
-            // ---------------------------------------------------------------------
-            // Get SQL and build grid
-            // ---------------------------------------------------------------------
-
-            sql = getAggregateReportSQL7WithoutGroupBy( programStage, orgunitIds, filterSQL, periods.iterator().next(),
-                aggregateType, useCompletedEvents, format );
+            deValues = dataElementService.getDataElement( deGroupBy ).getOptionSet().getOptions();
+
+            // ---------------------------------------------------------------------
+            // Headers cols
+            // ---------------------------------------------------------------------
+
+            grid.addHeader( new GridHeader( i18n.getString( "period" ), false, true ) );
+
+            for ( String deValue : deValues )
+            {
+                grid.addHeader( new GridHeader( deValue, false, false ) );
+            }
+
+            // ---------------------------------------------------------------------
+            // Get SQL and build grid
+            // ---------------------------------------------------------------------
+
+            sql = getAggregateReportSQL6( programStage, orgunitIds.iterator().next(), facilityLB, filterSQL, deGroupBy,
+                deValues, periods, aggregateType, useCompletedEvents, format );
+        }
+
+        // Type = 6 && NOT group-by
+        else if ( position == PatientAggregateReport.POSITION_ROW_PERIOD_COLUMN_DATA && deGroupBy == null )
+        {
+            // ---------------------------------------------------------------------
+            // Headers cols
+            // ---------------------------------------------------------------------
+
+            grid.addHeader( new GridHeader( i18n.getString( "period" ), false, true ) );
+            grid.addHeader( new GridHeader( i18n.getString( aggregateType ), false, false ) );
+
+            // ---------------------------------------------------------------------
+            // Get SQL and build grid
+            // ---------------------------------------------------------------------
+
+            sql = getAggregateReportSQL6WithoutGroup( programStage, orgunitIds.iterator().next(), facilityLB,
+                filterSQL, deGroupBy, periods, aggregateType, useCompletedEvents, format );
+        }
+
+        // Type = 7 && Group-by
+        else if ( position == PatientAggregateReport.POSITION_ROW_ORGUNIT_COLUMN_DATA && deGroupBy != null )
+        {
+            List<String> deValues = dataElementService.getDataElement( deGroupBy ).getOptionSet().getOptions();
+
+            // ---------------------------------------------------------------------
+            // Headers cols
+            // ---------------------------------------------------------------------
+
+            grid.addHeader( new GridHeader( i18n.getString( "orgunit" ), false, true ) );
+
+            for ( String deValue : deValues )
+            {
+                grid.addHeader( new GridHeader( deValue, false, false ) );
+            }
+
+            // ---------------------------------------------------------------------
+            // Get SQL and build grid
+            // ---------------------------------------------------------------------
+
+            sql = getAggregateReportSQL7( programStage, orgunitIds, facilityLB, filterSQL, deGroupBy, deValues, periods
+                .iterator().next(), aggregateType, useCompletedEvents, format );
+
+        }
+
+        // Type = 7 && NOT group-by
+        else if ( position == PatientAggregateReport.POSITION_ROW_ORGUNIT_COLUMN_DATA )
+        {
+            // ---------------------------------------------------------------------
+            // Headers cols
+            // ---------------------------------------------------------------------
+
+            grid.addHeader( new GridHeader( i18n.getString( "orgunit" ), false, true ) );
+            grid.addHeader( new GridHeader( i18n.getString( aggregateType ), false, false ) );
+
+            // ---------------------------------------------------------------------
+            // Get SQL and build grid
+            // ---------------------------------------------------------------------
+
+            sql = getAggregateReportSQL7WithoutGroup( programStage, orgunitIds, facilityLB, filterSQL, periods
+                .iterator().next(), aggregateType, useCompletedEvents, format );
+
         }
 
         // type = 8 && With group-by
         else if ( position == PatientAggregateReport.POSITION_ROW_DATA )
         {
-            DataElement dataElement = dataElementService.getDataElement( dataElementId );
-
             // ---------------------------------------------------------------------
             // Headers cols
             // ---------------------------------------------------------------------
 
-            grid.addHeader( new GridHeader( dataElement.getDisplayName(), false, true ) );
+            grid.addHeader( new GridHeader( i18n.getString( "data_element" ), false, true ) );
             grid.addHeader( new GridHeader( i18n.getString( aggregateType ), false, false ) );
 
             // ---------------------------------------------------------------------
             // Get SQL and build grid
             // ---------------------------------------------------------------------
 
-            sql = getAggregateReportSQL8( programStage, orgunitIds, dataElementId, periods.iterator().next(),
-                aggregateType, limit, useCompletedEvents, format );
+            sql = getAggregateReportSQL8( programStage, orgunitIds, facilityLB, filterSQL, deGroupBy, periods
+                .iterator().next(), aggregateType, limit, useCompletedEvents, format );
         }
-
+        System.out.println( "\n\n === \n " + sql );
         SqlRowSet rowSet = jdbcTemplate.queryForRowSet( sql );
 
         // Type != 2
@@ -790,136 +809,244 @@
      * Aggregate report Position Orgunit Columns - Period Rows - Data Filter
      * 
      **/
-    private String getAggregateReportSQL12( ProgramStage programStage, Collection<Integer> orgunitIds,
-        String filterSQL, Collection<Period> periods, String aggregateType, Boolean useCompletedEvents,
-        I18nFormat format )
+    private String getAggregateReportSQL12( ProgramStage programStage, Collection<Integer> roots, String facilityLB,
+        String filterSQL, Integer deGroupBy, Collection<Period> periods, String aggregateType,
+        Boolean useCompletedEvents, I18nFormat format )
     {
-        String sql = "select ou.name as orgunit, ";
-
-        for ( Period period : periods )
-        {
-
-            String periodName = "";
-            String startDate = format.formatDate( period.getStartDate() );
-            String endDate = format.formatDate( period.getEndDate() );
-            if ( period.getPeriodType() != null )
-            {
-                periodName = format.formatPeriod( period );
-            }
-            else
-            {
-                periodName = startDate + " -> " + endDate;
-            }
-            
-            sql += "( select count(*) ";
-            sql += "FROM programstageinstance psi_1 JOIN patientdatavalue pdv_1 ";
-            sql += "    ON psi_1.programstageinstanceid=pdv_1.programstageinstanceid ";
-            sql += "WHERE ";
-            sql += "    psi_1.organisationunitid = psi.organisationunitid AND ";
-            sql += "    psi_1.executiondate >= '" + startDate + "' AND ";
-            sql += "    psi_1.executiondate <= '" + endDate + "' ";
-
-            sql += filterSQL + " ) as \"" + periodName + "\",";
-        }
-
-        sql = sql.substring( 0, sql.length() - 1 ) + " ";
-
-        sql += "FROM programstageinstance psi ";
-        sql += "        RIGHT OUTER JOIN organisationunit ou on ou.organisationunitid=psi.organisationunitid ";
-        sql += "WHERE ";
-        sql += "   ou.organisationunitid in ( " + TextUtils.getCommaDelimitedString( orgunitIds ) + " )  AND ";
-        sql += "   psi.programstageid=" + programStage.getId() + " ";
-        if ( useCompletedEvents )
-        {
-            sql += " AND psi.completed = true  ";
-        }
-        sql += "GROUP BY ";
-        sql += "   ou.name, psi.organisationunitid ";
-        sql += "ORDER BY orgunit desc";
+        String sql = "";
+
+        // orgunit
+        for ( Integer root : roots )
+        {
+            Collection<Integer> orgunitIds = getOrganisationUnits( root, facilityLB );
+
+            sql += " (SELECT ";
+
+            sql += "( SELECT ou.name FROM organisationunit ou ";
+            sql += "WHERE ou.organisationunitid=" + root + " ) as orgunit, ";
+
+            // -- period
+            for ( Period period : periods )
+            {
+                String periodName = "";
+                String startDate = format.formatDate( period.getStartDate() );
+                String endDate = format.formatDate( period.getEndDate() );
+                if ( period.getPeriodType() != null )
+                {
+                    periodName = format.formatPeriod( period );
+                }
+                else
+                {
+                    periodName = startDate + " -> " + endDate;
+                }
+
+                sql += " ( SELECT " + aggregateType + "(*) ";
+                sql += "FROM programstageinstance psi_1 ";
+                sql += "        JOIN patientdatavalue pdv_1 ";
+                sql += "                ON psi_1.programstageinstanceid=pdv_1.programstageinstanceid ";
+                sql += "WHERE ";
+                sql += "     psi_1.organisationunitid in ( " + TextUtils.getCommaDelimitedString( orgunitIds )
+                    + " )  AND ";
+                sql += "     psi_1.executiondate >= '" + startDate + "' AND ";
+                sql += "     psi_1.executiondate <= '" + endDate + "' AND ";
+                if ( useCompletedEvents )
+                {
+                    sql += " psi_1.completed = true AND ";
+                }
+                if ( deGroupBy != null )
+                {
+                    sql += "(SELECT value from patientdatavalue ";
+                    sql += "WHERE programstageinstanceid=psi_1.programstageinstanceid AND ";
+                    sql += "      dataelementid=" + deGroupBy + ") is not null AND ";
+                }
+                sql += "     psi_1.programstageid=" + programStage.getId() + " ";
+                sql += filterSQL + "LIMIT 1 ) as \"" + periodName + "\" ,";
+            }
+            sql = sql.substring( 0, sql.length() - 1 ) + " ";
+            // -- end period
+
+            sql += " ) ";
+            sql += " UNION ";
+        }
+
+        sql = sql.substring( 0, sql.length() - 6 ) + " ";
+        sql += "ORDER BY orgunit asc";
 
         return sql;
     }
 
     /**
      * Generate SQL statement for 3 report type - Aggregate report Position
-     * Orgunit Rows - Period Rows - Data Filter Aggregate report Period Rows -
-     * Orgunit Filter - Data Filter
-     * 
-     **/
-    private String getAggregateReportSQL34( int position, ProgramStage programStage, Collection<Integer> orgunitIds,
-        String filterSQL, Collection<Period> periods, String aggregateType, Boolean useCompletedEvents,
-        I18nFormat format )
-    {
-        String sql = "";
-
-        for ( Period period : periods )
-        {
-            String periodName = "";
-            String startDate = format.formatDate( period.getStartDate() );
-            String endDate = format.formatDate( period.getEndDate() );
-            if ( period.getPeriodType() != null )
-            {
-                periodName = format.formatPeriod( period );
-            }
-            else
-            {
-                periodName = startDate + " -> " + endDate;
-            }
-            
-            sql += "( " + getColumnAggregateReportSQL34( position, periodName, aggregateType ) + " ";
+     * Orgunit Rows - Period Rows - Data Filter
+     * 
+     **/
+    private String getAggregateReportSQL3( int position, ProgramStage programStage, Collection<Integer> roots,
+        String facilityLB, String filterSQL, Integer deGroupBy, Collection<Period> periods, String aggregateType,
+        Boolean useCompletedEvents, I18nFormat format )
+    {
+        String sql = "";
+
+        for ( Integer root : roots )
+        {
+            Collection<Integer> orgunitIds = getOrganisationUnits( root, facilityLB );
+
+            for ( Period period : periods )
+            {
+                String periodName = "";
+                String startDate = format.formatDate( period.getStartDate() );
+                String endDate = format.formatDate( period.getEndDate() );
+                if ( period.getPeriodType() != null )
+                {
+                    periodName = format.formatPeriod( period );
+                }
+                else
+                {
+                    periodName = startDate + " -> " + endDate;
+                }
+
+                sql += "( SELECT ";
+                sql += "( SELECT ou.name FROM organisationunit ou WHERE organisationunitid=" + root + " ) as orgunit, ";
+                sql += "'" + periodName + "' , ";
+
+                sql += " ( SELECT " + aggregateType + "(pdv_1.value)   ";
+                sql += "FROM ";
+                sql += "   patientdatavalue pdv_1 JOIN programstageinstance psi_1 ";
+                sql += "        ON psi_1.programstageinstanceid=pdv_1.programstageinstanceid ";
+                sql += "   JOIN organisationunit ou on (ou.organisationunitid=psi_1.organisationunitid ) ";
+                sql += "WHERE ";
+                sql += "    ou.organisationunitid in ( " + TextUtils.getCommaDelimitedString( orgunitIds ) + " ) AND ";
+                sql += "    psi_1.programstageid=" + programStage.getId() + " AND ";
+                if ( useCompletedEvents )
+                {
+                    sql += " psi_1.completed = true AND ";
+                }
+                if ( deGroupBy != null )
+                {
+                    sql += "(SELECT value from patientdatavalue ";
+                    sql += "WHERE programstageinstanceid=psi_1.programstageinstanceid AND ";
+                    sql += "      dataelementid=" + deGroupBy + ") is not null AND ";
+                }
+                sql += "     psi_1.executiondate >= '" + startDate + "' AND ";
+                sql += "     psi_1.executiondate <= '" + endDate + "' ";
+                sql += filterSQL + " ) ) ";
+                sql += " UNION ";
+            }
+        }
+
+        sql = sql.substring( 0, sql.length() - 6 ) + " ";
+
+        sql += "ORDER BY orgunit asc";
+
+        return sql;
+    }
+
+    /**
+     * Aggregate report Period Rows - Orgunit Filter - Data Filter
+     * 
+     **/
+    private String getAggregateReportSQL4( int position, ProgramStage programStage, Collection<Integer> roots,
+        String facilityLB, String filterSQL, Integer deGroupBy, Collection<Period> periods, String aggregateType,
+        Boolean useCompletedEvents, I18nFormat format )
+    {
+        String sql = "";
+
+        for ( Integer root : roots )
+        {
+            Collection<Integer> orgunitIds = getOrganisationUnits( root, facilityLB );
+
+            for ( Period period : periods )
+            {
+                String periodName = "";
+                String startDate = format.formatDate( period.getStartDate() );
+                String endDate = format.formatDate( period.getEndDate() );
+                if ( period.getPeriodType() != null )
+                {
+                    periodName = format.formatPeriod( period );
+                }
+                else
+                {
+                    periodName = startDate + " -> " + endDate;
+                }
+
+                sql += "( SELECT ";
+                sql += "'" + periodName + "' , ";
+
+                sql += " ( SELECT " + aggregateType + "(pdv_1.value)   ";
+                sql += "FROM ";
+                sql += "   patientdatavalue pdv_1 JOIN programstageinstance psi_1 ";
+                sql += "        ON psi_1.programstageinstanceid=pdv_1.programstageinstanceid ";
+                sql += "   JOIN organisationunit ou on (ou.organisationunitid=psi_1.organisationunitid ) ";
+                sql += "WHERE ";
+                sql += "    ou.organisationunitid in ( " + TextUtils.getCommaDelimitedString( orgunitIds ) + " ) AND ";
+                sql += "    psi_1.programstageid=" + programStage.getId() + " AND ";
+                if ( useCompletedEvents )
+                {
+                    sql += " psi_1.completed = true AND ";
+                }
+                if ( deGroupBy != null )
+                {
+                    sql += "(SELECT value from patientdatavalue ";
+                    sql += "WHERE programstageinstanceid=psi_1.programstageinstanceid AND ";
+                    sql += "      dataelementid=" + deGroupBy + ") is not null AND ";
+                }
+                sql += "     psi_1.executiondate >= '" + startDate + "' AND ";
+                sql += "     psi_1.executiondate <= '" + endDate + "' ";
+                sql += filterSQL + " ) ) ";
+                sql += " UNION ";
+            }
+        }
+
+        sql = sql.substring( 0, sql.length() - 6 );
+
+        return sql;
+    }
+
+    /**
+     * Aggregate report Position Orgunit Rows -Period Filter - Data Filter
+     * 
+     **/
+    private String getAggregateReportSQL5( int position, ProgramStage programStage, Collection<Integer> roots,
+        String facilityLB, String filterSQL, Integer deGroupBy, Period period, String aggregateType,
+        Boolean useCompletedEvents, I18nFormat format )
+    {
+        String sql = "";
+
+        for ( Integer root : roots )
+        {
+            Collection<Integer> orgunitIds = getOrganisationUnits( root, facilityLB );
+
+            sql += "( SELECT  ";
+            sql += "( SELECT ou.name  ";
+            sql += "FROM organisationunit ou  ";
+            sql += "WHERE ou.organisationunitid=" + root + " ) as orgunit, ";
+
+            sql += "(select " + aggregateType + "(pdv_1.value)  ";
             sql += "FROM ";
-            sql += "patientdatavalue pdv_1 JOIN programstageinstance psi_1 ";
-            sql += "       ON psi_1.programstageinstanceid=pdv_1.programstageinstanceid ";
-            sql += "JOIN organisationunit ou on (ou.organisationunitid=psi_1.organisationunitid ) ";
-            sql += " WHERE ";
-            sql += "      ou.organisationunitid in ( " + TextUtils.getCommaDelimitedString( orgunitIds ) + " ) AND ";
-            sql += "      psi_1.programstageid=" + programStage.getId() + " AND ";
+            sql += "    patientdatavalue pdv_1 RIGHT JOIN programstageinstance psi_1 ";
+            sql += "            ON psi_1.programstageinstanceid=pdv_1.programstageinstanceid ";
+            sql += "WHERE ";
+            sql += "    psi_1.organisationunitid in ( " + TextUtils.getCommaDelimitedString( orgunitIds ) + " ) AND ";
+            sql += "    psi_1.programstageid=" + programStage.getId() + " AND ";
+            sql += "    psi_1.executiondate >= '" + format.formatDate( period.getStartDate() ) + "' AND ";
+            sql += "    psi_1.executiondate <= '" + format.formatDate( period.getEndDate() ) + "' ";
+            sql += filterSQL + " ";
+            if ( deGroupBy != null )
+            {
+                sql += " AND (SELECT value from patientdatavalue ";
+                sql += "WHERE programstageinstanceid=psi_1.programstageinstanceid AND ";
+                sql += "      dataelementid=" + deGroupBy + ") is not null ";
+            }
             if ( useCompletedEvents )
             {
-                sql += " psi_1.completed=true AND ";
-            }
-            sql += "      psi_1.executiondate >= '" + startDate + "' AND ";
-            sql += "      psi_1.executiondate <= '" + endDate + "' ";
-            sql += filterSQL;
-            if ( position == PatientAggregateReport.POSITION_ROW_ORGUNIT_ROW_PERIOD )
-            {
-                sql += "GROUP BY ou.name  ";
-            }
-            sql += ")  UNION ";
-        }
-
-        sql += sql.substring( 0, sql.length() - 6 );
-        if ( position == PatientAggregateReport.POSITION_ROW_ORGUNIT_ROW_PERIOD )
-        {
-            sql += " ORDER BY orgunit desc";
-        }
-        return sql;
-    }
-
-    /**
-     * Aggregate report Position Orgunit Rows -Period Filter - Data Filter
-     * 
-     **/
-    private String getAggregateReportSQL5( int position, ProgramStage programStage, Collection<Integer> orgunitIds,
-        String filterSQL, Period period, String aggregateType, Boolean useCompletedEvents, I18nFormat format )
-    {
-        String sql = "SELECT ou.name as orgunit, count(pdv_1.value) ";
-        sql += "FROM ";
-        sql += "        patientdatavalue pdv_1 RIGHT JOIN programstageinstance psi_1 ";
-        sql += "                ON psi_1.programstageinstanceid=pdv_1.programstageinstanceid ";
-        sql += "        JOIN organisationunit ou on (ou.organisationunitid=psi_1.organisationunitid ) ";
-        sql += "WHERE ";
-        sql += "        ou.organisationunitid in ( " + TextUtils.getCommaDelimitedString( orgunitIds ) + " ) AND ";
-        sql += "        psi_1.programstageid=" + programStage.getId() + " AND ";
-        if ( useCompletedEvents )
-        {
-            sql += " psi_1.completed = true AND ";
-        }
-        sql += "        psi_1.executiondate >= '" + format.formatDate( period.getStartDate() ) + "' AND ";
-        sql += "        psi_1.executiondate <= '" + format.formatDate( period.getEndDate() ) + "' ";
-        sql += filterSQL;
-        sql += "GROUP BY ou.name ";
-        sql += "ORDER BY orgunit desc  ";
+                sql += " AND psi_1.completed = true ";
+            }
+            sql += " )  ) ";
+            sql += " UNION ";
+        }
+
+        sql = sql.substring( 0, sql.length() - 6 ) + " ";
+
+        sql += "ORDER BY orgunit asc";
 
         return sql;
     }
@@ -928,13 +1055,16 @@
      * Aggregate report Position Orgunit Filter - Period Rows - Data Columns
      * with group-by
      **/
-    private String getAggregateReportSQL6( ProgramStage programStage, Collection<Integer> orgunitIds, String filterSQL,
-        Integer dataElementId, Collection<String> deValues, Collection<Period> periods, String aggregateType,
-        Boolean useCompletedEvents, I18nFormat format )
+    private String getAggregateReportSQL6( ProgramStage programStage, Integer root, String facilityLB,
+        String filterSQL, Integer deGroupBy, Collection<String> deValues, Collection<Period> periods,
+        String aggregateType, Boolean useCompletedEvents, I18nFormat format )
     {
         String sql = "";
 
         int index = 0;
+
+        Collection<Integer> orgunitIds = getOrganisationUnits( root, facilityLB );
+
         for ( Period period : periods )
         {
             String periodName = "";
@@ -948,7 +1078,7 @@
             {
                 periodName = startDate + " -> " + endDate;
             }
-            
+
             sql += "(SELECT '" + periodName + "', ";
             for ( String deValue : deValues )
             {
@@ -962,10 +1092,9 @@
                 sql += "    psi_1.executiondate <= '" + endDate + "' ";
                 sql += filterSQL + " AND ";
                 sql += "        (SELECT value from patientdatavalue ";
-                sql += "        WHERE programstageinstanceid=psi_1.programstageinstanceid ";
-                sql += "                AND dataelementid=" + dataElementId + " ";
-                sql += "        ) = '" + deValue + "' ";
-                sql += ") as de_value" + index + ",";
+                sql += "        WHERE programstageinstanceid=psi_1.programstageinstanceid AND ";
+                sql += "              dataelementid=" + deGroupBy + ") = '" + deValue + "' ";
+                sql += ") as de_value_" + index + ",";
 
                 index++;
             }
@@ -982,23 +1111,26 @@
             }
             sql += "GROUP BY dataelementid ";
             sql += "  LIMIT 1 ";
+
             sql += ") UNION ";
+
         }
 
-        return sql.substring( 0, sql.length() - 6 ) + " ";
+        return sql.substring( 0, sql.length() - 6 );
     }
 
     /**
      * Aggregate report Position Orgunit Filter - Period Rows - Data Columns
      * without group-by
      **/
-    private String getAggregateReportSQL6NotGroupBy( ProgramStage programStage, Collection<Integer> orgunitIds,
-        String filterSQL, Collection<Period> periods, String aggregateType, Boolean useCompletedEvents,
-        I18nFormat format )
+    private String getAggregateReportSQL6WithoutGroup( ProgramStage programStage, Integer root, String facilityLB,
+        String filterSQL, Integer deGroupBy, Collection<Period> periods, String aggregateType,
+        Boolean useCompletedEvents, I18nFormat format )
     {
         String sql = "";
 
-        int index = 0;
+        Collection<Integer> orgunitIds = getOrganisationUnits( root, facilityLB );
+
         for ( Period period : periods )
         {
             String periodName = "";
@@ -1012,8 +1144,9 @@
             {
                 periodName = startDate + " -> " + endDate;
             }
-            
+
             sql += "(SELECT '" + periodName + "', ";
+
             sql += "(SELECT " + aggregateType + "(value)  ";
             sql += "FROM programstageinstance psi_1 JOIN patientdatavalue pdv_1 ";
             sql += "    on psi_1.programstageinstanceid = pdv_1.programstageinstanceid ";
@@ -1022,7 +1155,13 @@
                 + "     ) AND ";
             sql += "    psi_1.executiondate >= '" + startDate + "' AND ";
             sql += "    psi_1.executiondate <= '" + endDate + "' ";
-            sql += filterSQL + ") as de_value" + index + ",";
+            if ( deGroupBy != null )
+            {
+                sql += " AND (SELECT value from patientdatavalue ";
+                sql += "WHERE programstageinstanceid=psi_1.programstageinstanceid AND ";
+                sql += "      dataelementid=" + deGroupBy + ") is not null ";
+            }
+            sql += filterSQL + "),";
 
             sql = sql.substring( 0, sql.length() - 1 ) + " ";
 
@@ -1037,128 +1176,138 @@
             }
             sql += "GROUP BY dataelementid ";
             sql += "  LIMIT 1 ";
+
             sql += ") UNION ";
-            index++;
-        }
-
-        return sql.substring( 0, sql.length() - 6 ) + " ";
-    }
-
-    /**
-     * Aggregate report Position Orgunit Rows - Period Filter - Data Columns
-     * 
-     **/
-    private String getAggregateReportSQL7( ProgramStage programStage, Collection<Integer> orgunitIds, String filterSQL,
-        Integer dataElementId, List<String> deValues, Period period, String aggregateType, Boolean useCompletedEvents,
+        }
+
+        return sql.substring( 0, sql.length() - 6 );
+    }
+
+    /**
+     * Aggregate report Position Orgunit Rows - Period Filter - Data Columns
+     * 
+     **/
+    private String getAggregateReportSQL7( ProgramStage programStage, Collection<Integer> roots, String facilityLB,
+        String filterSQL, Integer deGroupBy, List<String> deValues, Period period, String aggregateType,
+        Boolean useCompletedEvents, I18nFormat format )
+    {
+        String sql = "";
+
+        for ( Integer root : roots )
+        {
+            Collection<Integer> orgunitIds = getOrganisationUnits( root, facilityLB );
+
+            sql += "(SELECT ";
+            sql += "( SELECT ou.name FROM organisationunit ou WHERE ou.organisationunitid=" + root + " ) as orgunit, ";
+            for ( String deValue : deValues )
+            {
+                sql += "( SELECT " + aggregateType + "(value) FROM patientdatavalue pdv_1 ";
+                sql += "        inner join programstageinstance psi_1 ";
+                sql += "          on psi_1.programstageinstanceid = pdv_1.programstageinstanceid ";
+                sql += "WHERE ";
+                sql += "        psi_1.executiondate >= '" + format.formatDate( period.getStartDate() ) + "' AND ";
+                sql += "        psi_1.executiondate <= '" + format.formatDate( period.getEndDate() ) + "' AND ";
+                sql += "        psi_1.organisationunitid in (" + TextUtils.getCommaDelimitedString( orgunitIds )
+                    + ") AND ";
+                if ( useCompletedEvents )
+                {
+                    sql += " psi_1.completed = true AND ";
+                }
+                sql += "        psi_1.programstageid=" + programStage.getId() + " ";
+                sql += filterSQL + " AND ";
+                sql += "   (SELECT value FROM patientdatavalue  ";
+                sql += "   WHERE programstageinstanceid=psi_1.programstageinstanceid AND ";
+                sql += "     dataelementid= pdv_1.dataelementid AND ";
+                sql += "     dataelementid=" + deGroupBy + "  ) = '" + deValue + "' ";
+                sql += "),";
+            }
+
+            sql = sql.substring( 0, sql.length() - 1 ) + " ) ";
+            sql += " UNION ";
+        }
+
+        sql = sql.substring( 0, sql.length() - 6 );
+
+        return sql;
+    }
+
+    /**
+     * Aggregate report Position Orgunit Rows - Period Filter - Data Columns
+     * 
+     **/
+    private String getAggregateReportSQL7WithoutGroup( ProgramStage programStage, Collection<Integer> roots,
+        String facilityLB, String filterSQL, Period period, String aggregateType, Boolean useCompletedEvents,
         I18nFormat format )
     {
-        String sql = "select ou.name as orgunit, ";
-
-        int index = 0;
-        for ( String deValue : deValues )
-        {
-            sql += "( select " + aggregateType + "(value) ";
+
+        String sql = "";
+
+        for ( Integer root : roots )
+        {
+            Collection<Integer> orgunitIds = getOrganisationUnits( root, facilityLB );
+
+            sql += "(SELECT ";
+            sql += "( SELECT ou.name FROM organisationunit ou WHERE ou.organisationunitid=" + root + " ) as orgunit, ";
+
+            sql += "( SELECT " + aggregateType + "(value) FROM patientdatavalue pdv_1 ";
+            sql += "        inner join programstageinstance psi_1 ";
+            sql += "          on psi_1.programstageinstanceid = pdv_1.programstageinstanceid ";
+            sql += "WHERE ";
+            sql += "        psi_1.executiondate >= '" + format.formatDate( period.getStartDate() ) + "' AND ";
+            sql += "        psi_1.executiondate <= '" + format.formatDate( period.getEndDate() ) + "' AND ";
+            if ( useCompletedEvents )
+            {
+                sql += " psi_1.completed = true AND ";
+            }
+            sql += "        psi_1.organisationunitid in (" + TextUtils.getCommaDelimitedString( orgunitIds ) + ") AND ";
+            sql += "        psi_1.programstageid=" + programStage.getId() + " ";
+            sql += filterSQL + ") ) ";
+
+            sql += " UNION ";
+        }
+
+        return sql.substring( 0, sql.length() - 6 );
+    }
+
+    /**
+     * Aggregate report Position Data Rows
+     * 
+     **/
+    private String getAggregateReportSQL8( ProgramStage programStage, Collection<Integer> roots, String facilityLB,
+        String filterSQL, Integer deGroupBy, Period period, String aggregateType, Integer limit,
+        Boolean useCompletedEvents, I18nFormat format )
+    {
+        String sql = "";
+        for ( Integer root : roots )
+        {
+            Collection<Integer> orgunitIds = getOrganisationUnits( root, facilityLB );
+
+            sql += "(SELECT pdv_1.value, " + aggregateType + "(pdv_1.value) as \"" + aggregateType + "\" ";
             sql += "FROM patientdatavalue pdv_1 ";
-            sql += "    inner join programstageinstance psi_1 ";
-            sql += "    on psi_1.programstageinstanceid = pdv_1.programstageinstanceid ";
+            sql += "    JOIN programstageinstance psi_1 ";
+            sql += "            ON psi_1.programstageinstanceid = pdv_1.programstageinstanceid ";
             sql += "WHERE ";
-            sql += "    psi_1.organisationunitid=psi.organisationunitid AND ";
+            sql += " psi_1.programstageid=" + programStage.getId() + " AND ";
+            if ( useCompletedEvents )
+            {
+                sql += " psi_1.completed = true AND ";
+            }
             sql += "    psi_1.executiondate >= '" + format.formatDate( period.getStartDate() ) + "' AND ";
             sql += "    psi_1.executiondate <= '" + format.formatDate( period.getEndDate() ) + "' AND ";
-            sql += "    psi_1.programstageid=" + programStage.getId() + " AND ";
-            if ( useCompletedEvents )
+            sql += "    psi_1.organisationunitid in( " + TextUtils.getCommaDelimitedString( orgunitIds ) + " )  ";
+            if ( deGroupBy != null )
             {
-                sql += " psi_1.completed = true AND ";
+                sql += " AND pdv_1.dataelementid=" + deGroupBy + " ";
             }
-            sql += "    pdv_1.value='" + deValue + "' ";
-            sql += filterSQL + " AND ";
-            sql += "    (SELECT value from patientdatavalue ";
-            sql += "     WHERE programstageinstanceid=psi_1.programstageinstanceid ";
-            sql += "            AND dataelementid=" + dataElementId + " ";
-            sql += "     ) = '" + deValue + "' ";
-
-            sql += ") as v_" + index + ",";
-
-            index++;
-        }
-        sql = sql.substring( 0, sql.length() - 1 ) + " ";
-
-        sql += "FROM programstageinstance psi ";
-        sql += "        RIGHT JOIN organisationunit ou on ou.organisationunitid=psi.organisationunitid ";
-        sql += "WHERE ";
-        sql += "        ou.organisationunitid in ( " + TextUtils.getCommaDelimitedString( orgunitIds ) + ") ";
-        sql += "GROUP BY ";
-        sql += "        psi.organisationunitid,ou.name ";
-        sql += "ORDER BY orgunit desc ";
-
-        return sql;
-    }
-
-    /**
-     * Aggregate report Position Orgunit Rows - Period Filter - Data Columns
-     * without group-by
-     **/
-    private String getAggregateReportSQL7WithoutGroupBy( ProgramStage programStage, Collection<Integer> orgunitIds,
-        String filterSQL, Period period, String aggregateType, Boolean useCompletedEvents, I18nFormat format )
-    {
-        String sql = "select ou.name as orgunit, ";
-
-        sql += "( select " + aggregateType + "(value) ";
-        sql += "FROM patientdatavalue pdv_1 ";
-        sql += "    inner join programstageinstance psi_1 ";
-        sql += "    on psi_1.programstageinstanceid = pdv_1.programstageinstanceid ";
-        sql += "WHERE ";
-        sql += "    psi_1.organisationunitid=psi.organisationunitid AND ";
-        sql += "    psi_1.executiondate >= '" + format.formatDate( period.getStartDate() ) + "' AND ";
-        sql += "    psi_1.executiondate <= '" + format.formatDate( period.getEndDate() ) + "' AND ";
-        sql += "    psi_1.programstageid=" + programStage.getId() + " ";
-        if ( useCompletedEvents )
-        {
-            sql += " AND psi_1.completed = true ";
-        }
-        sql += filterSQL + " ) ";
-        sql += "FROM programstageinstance psi ";
-        sql += "        RIGHT JOIN organisationunit ou on ou.organisationunitid=psi.organisationunitid ";
-        sql += "WHERE ";
-        sql += "        ou.organisationunitid in ( " + TextUtils.getCommaDelimitedString( orgunitIds ) + ") ";
-        sql += "GROUP BY ";
-        sql += "        psi.organisationunitid,ou.name ";
-        sql += "ORDER BY orgunit desc ";
-
-        return sql;
-    }
-
-    /**
-     * Aggregate report Position Data Rows
-     * 
-     **/
-    private String getAggregateReportSQL8( ProgramStage programStage, Collection<Integer> orgunitIds,
-        Integer dataElementId, Period period, String aggregateType, Integer limit, Boolean useCompletedEvents,
-        I18nFormat format )
-    {
-        String from = "FROM patientdatavalue pdv ";
-        from += "        JOIN programstageinstance psi ";
-        from += "          ON psi.programstageinstanceid = pdv.programstageinstanceid  ";
-        from += "WHERE ";
-        from += "    pdv.dataelementid=" + dataElementId + " AND  ";
-        from += "    psi.programstageid=" + programStage.getId() + " AND ";
-        if ( useCompletedEvents )
-        {
-            from += " psi.completed = true AND ";
-        }
-        from += "    psi.executiondate >= '" + format.formatDate( period.getStartDate() ) + "' AND ";
-        from += "    psi.executiondate <= '" + format.formatDate( period.getEndDate() ) + "' AND ";
-        from += "    psi.organisationunitid in ( " + TextUtils.getCommaDelimitedString( orgunitIds ) + " ) ";
-
-        String sql = " SELECT ov.optionvalue,'0' ";
-        sql += "FROM optionset op JOIN optionsetmembers ov ";
-        sql += "        ON op.optionsetid=ov.optionsetid ";
-        sql += "JOIN dataelement de ";
-        sql += "        ON de.optionsetid=op.optionsetid ";
-        sql += "WHERE de.dataelementid=" + dataElementId + " AND ov.optionvalue not in  ";
-
-        sql = "( SELECT pdv.value, " + aggregateType + "(value) " + from + "GROUP BY pdv.value " + "ORDER BY "
-            + aggregateType + "(value) desc ) UNION ( " + sql + " " + "(SELECT DISTINCT pdv.value " + from + ") )";
+            sql += filterSQL + " ";
+            sql += "GROUP BY pdv_1.value )";
+            sql += " UNION ";
+        }
+
+        sql = sql.substring( 0, sql.length() - 6 ) + " ";
+
+        sql += "ORDER BY  \"" + aggregateType + "\" desc ";
+
         if ( limit != null )
         {
             sql += "LIMIT " + limit;
@@ -1167,24 +1316,6 @@
         return sql;
     }
 
-    /**
-     * Generate SELECT statement for 3 report type - Aggregate report Position
-     * Orgunit Rows - Period Rows - Data Filter
-     * 
-     **/
-    private String getColumnAggregateReportSQL34( int position, String periodColumnName, String aggregateType )
-    {
-        switch ( position )
-        {
-        case PatientAggregateReport.POSITION_ROW_ORGUNIT_ROW_PERIOD:
-            return "select ou.name as orgunit, '" + periodColumnName + "', " + aggregateType + "(pdv_1.value) ";
-        case PatientAggregateReport.POSITION_ROW_PERIOD:
-            return "select '" + periodColumnName + "', count(pdv_1.value) ";
-        default:
-            return "";
-        }
-    }
-
     private void pivotTable( Grid grid, SqlRowSet rowSet )
     {
         try
@@ -1255,7 +1386,7 @@
                     flag = true;
                 }
                 filter += "dataelementid=" + id + "  ";
-                filter += ") " + filterKey[0] + " '" + filterKey[1] + "' ";
+                filter += ") " + filterKey[0] + " " + filterKey[1] + " ";
 
                 if ( filterKey.length == 4 )
                 {
@@ -1263,7 +1394,7 @@
                     filter += "FROM patientdatavalue ";
                     filter += "WHERE programstageinstanceid=psi_1.programstageinstanceid AND ";
                     filter += "dataelementid=" + id + "  ";
-                    filter += ") " + filterKey[2] + " '" + filterKey[3] + "' ";
+                    filter += ") " + filterKey[2] + " " + filterKey[3] + " ";
                 }
             }
         }
@@ -1271,4 +1402,28 @@
         return filter;
     }
 
+    // ---------------------------------------------------------------------
+    // Get orgunitIds
+    // ---------------------------------------------------------------------
+
+    private Collection<Integer> getOrganisationUnits( Integer root, String facilityLB )
+    {
+        Set<Integer> orgunitIds = new HashSet<Integer>();
+
+        if ( facilityLB.equals( "selected" ) )
+        {
+            orgunitIds.add( root );
+        }
+        else if ( facilityLB.equals( "childrenOnly" ) )
+        {
+            orgunitIds.addAll( organisationUnitService.getOrganisationUnitHierarchy().getChildren( root ) );
+            orgunitIds.remove( root );
+        }
+        else
+        {
+            orgunitIds.addAll( organisationUnitService.getOrganisationUnitHierarchy().getChildren( root ) );
+        }
+
+        return orgunitIds;
+    }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-patient/src/main/resources/META-INF/dhis/beans.xml	2013-01-14 04:49:57 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/resources/META-INF/dhis/beans.xml	2013-01-21 06:18:31 +0000
@@ -33,6 +33,7 @@
 		<property name="jdbcTemplate" ref="jdbcTemplate" />
 		<property name="statementBuilder" ref="statementBuilder" />
 		<property name="dataElementService" ref="org.hisp.dhis.dataelement.DataElementService" />
+		<property name="organisationUnitService" ref="org.hisp.dhis.organisationunit.OrganisationUnitService" />
 	</bean>
 
 	<bean id="org.hisp.dhis.program.ProgramInstanceStore"

=== modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/report/GenerateAggregateReportAction.java'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/report/GenerateAggregateReportAction.java	2013-01-17 08:06:51 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/report/GenerateAggregateReportAction.java	2013-01-21 06:18:31 +0000
@@ -33,14 +33,11 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import org.hisp.dhis.common.Grid;
 import org.hisp.dhis.i18n.I18n;
 import org.hisp.dhis.i18n.I18nFormat;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
-import org.hisp.dhis.organisationunit.OrganisationUnitService;
-import org.hisp.dhis.period.MonthlyPeriodType;
 import org.hisp.dhis.period.Period;
 import org.hisp.dhis.period.PeriodService;
 import org.hisp.dhis.period.PeriodType;
@@ -48,6 +45,7 @@
 import org.hisp.dhis.program.ProgramStage;
 import org.hisp.dhis.program.ProgramStageInstanceService;
 import org.hisp.dhis.program.ProgramStageService;
+import org.hisp.dhis.user.CurrentUserService;
 
 import com.opensymphony.xwork2.Action;
 
@@ -79,13 +77,6 @@
         this.programStageService = programStageService;
     }
 
-    private OrganisationUnitService organisationUnitService;
-
-    public void setOrganisationUnitService( OrganisationUnitService organisationUnitService )
-    {
-        this.organisationUnitService = organisationUnitService;
-    }
-
     private PeriodService periodService;
 
     public void setPeriodService( PeriodService periodService )
@@ -93,6 +84,13 @@
         this.periodService = periodService;
     }
 
+    private CurrentUserService currentUserService;
+
+    public void setCurrentUserService( CurrentUserService currentUserService )
+    {
+        this.currentUserService = currentUserService;
+    }
+
     private I18nFormat format;
 
     public void setFormat( I18nFormat format )
@@ -125,7 +123,7 @@
         this.aggregateType = aggregateType;
     }
 
-    private Collection<Integer> orgunitIds;
+    private Collection<Integer> orgunitIds = new HashSet<Integer>();
 
     public void setOrgunitIds( Collection<Integer> orgunitIds )
     {
@@ -202,6 +200,20 @@
         this.useCompletedEvents = useCompletedEvents;
     }
 
+    private Boolean userOrganisationUnit;
+
+    public void setUserOrganisationUnit( Boolean userOrganisationUnit )
+    {
+        this.userOrganisationUnit = userOrganisationUnit;
+    }
+
+    private Boolean userOrganisationUnitChildren;
+
+    public void setUserOrganisationUnitChildren( Boolean userOrganisationUnitChildren )
+    {
+        this.userOrganisationUnitChildren = userOrganisationUnitChildren;
+    }
+
     private String type;
 
     public void setType( String type )
@@ -227,31 +239,35 @@
     public String execute()
     {
         // ---------------------------------------------------------------------
-        // Get orgunitIds
+        // Get user orgunits
         // ---------------------------------------------------------------------
 
-        Set<Integer> organisationUnits = new HashSet<Integer>();
+        Collection<OrganisationUnit> userOrgunits = currentUserService.getCurrentUser().getOrganisationUnits();
+        
+        if ( userOrganisationUnit || userOrganisationUnitChildren )
+        {
+            orgunitIds = new HashSet<Integer>();
 
-        if ( facilityLB.equals( "selected" ) )
-        {
-            organisationUnits.addAll( orgunitIds );
-        }
-        else if ( facilityLB.equals( "childrenOnly" ) )
-        {
-            for ( Integer orgunitId : orgunitIds )
+            if ( userOrganisationUnit )
             {
-                OrganisationUnit selectedOrgunit = organisationUnitService.getOrganisationUnit( orgunitId );
-                organisationUnits.addAll( organisationUnitService.getOrganisationUnitHierarchy()
-                    .getChildren( orgunitId ) );
-                organisationUnits.remove( selectedOrgunit );
+                for ( OrganisationUnit userOrgunit : userOrgunits )
+                {
+                    orgunitIds.add( userOrgunit.getId() );
+                }
             }
-        }
-        else
-        {
-            for ( Integer orgunitId : orgunitIds )
+
+            if ( userOrganisationUnitChildren )
             {
-                organisationUnits.addAll( organisationUnitService.getOrganisationUnitHierarchy()
-                    .getChildren( orgunitId ) );
+                for ( OrganisationUnit userOrgunit : userOrgunits )
+                {
+                    if ( userOrgunit.hasChild() )
+                    {
+                        for ( OrganisationUnit childOrgunit : userOrgunit.getSortedChildren() )
+                        {
+                            orgunitIds.add( childOrgunit.getId() );
+                        }
+                    }
+                }
             }
         }
 
@@ -292,13 +308,13 @@
             for ( String deFilter : deFilters )
             {
                 int index = deFilter.indexOf( SEPARATE_FILTER );
-                deFilterMap.put( Integer.parseInt( deFilter.substring( 0, index - 1 ) ),
+                deFilterMap.put( Integer.parseInt( deFilter.substring( 0, index ) ),
                     deFilter.substring( index + 1, deFilter.length() ) );
             }
         }
-        
-        grid = programStageInstanceService.getAggregateReport( position, programStage, organisationUnits, deGroupBy,
-            deFilterMap, periods, aggregateType, limitRecords, useCompletedEvents, format, i18n );
+
+        grid = programStageInstanceService.getAggregateReport( position, programStage, orgunitIds, facilityLB,
+            deGroupBy, deFilterMap, periods, aggregateType, limitRecords, useCompletedEvents, format, i18n );
 
         return type == null ? SUCCESS : type;
     }

=== modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/report/GetOrganisationUnitChildrenAction.java'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/report/GetOrganisationUnitChildrenAction.java	2012-04-11 06:25:02 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/report/GetOrganisationUnitChildrenAction.java	2013-01-21 06:18:31 +0000
@@ -58,9 +58,9 @@
     // Input
     // -------------------------------------------------------------------------
 
-    private Integer node;
+    private String node;
     
-    public void setNode( Integer node )
+    public void setNode( String node )
     {
         this.node = node;
     }

=== added file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/report/GetOrganisationUnitsByGroupAction.java'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/report/GetOrganisationUnitsByGroupAction.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/report/GetOrganisationUnitsByGroupAction.java	2013-01-21 06:18:31 +0000
@@ -0,0 +1,91 @@
+package org.hisp.dhis.caseentry.action.report;
+
+/*
+ * Copyright (c) 2004-2012, 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 java.util.ArrayList;
+import java.util.Collection;
+
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.organisationunit.OrganisationUnitGroupService;
+
+import com.opensymphony.xwork2.Action;
+
+/**
+ * @author Jan Henrik Overland
+ */
+public class GetOrganisationUnitsByGroupAction
+    implements Action
+{
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    private OrganisationUnitGroupService organisationUnitGroupService;
+
+    public void setOrganisationUnitGroupService( OrganisationUnitGroupService organisationUnitGroupService )
+    {
+        this.organisationUnitGroupService = organisationUnitGroupService;
+    }
+    
+    // -------------------------------------------------------------------------
+    // Input
+    // -------------------------------------------------------------------------
+
+    private String id;
+
+    public void setId( String id )
+    {
+        this.id = id;
+    }
+
+    // -------------------------------------------------------------------------
+    // Output
+    // -------------------------------------------------------------------------
+
+    private Collection<OrganisationUnit> object = new ArrayList<OrganisationUnit>();
+
+    public Collection<OrganisationUnit> getObject()
+    {
+        return object;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    public String execute()
+        throws Exception
+    {
+        if ( id != null )
+        {
+            object = organisationUnitGroupService.getOrganisationUnitGroup( id ).getMembers();
+        }
+
+        return SUCCESS;
+    }
+}

=== modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/resources/META-INF/dhis/beans.xml	2013-01-17 02:28:42 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/resources/META-INF/dhis/beans.xml	2013-01-21 06:18:31 +0000
@@ -242,8 +242,9 @@
 		<property name="programStageInstanceService"
 			ref="org.hisp.dhis.program.ProgramStageInstanceService" />
 	</bean>
-	
-	<bean id="org.hisp.dhis.caseentry.action.report.GenerateStatisticalProgramReportAction"
+
+	<bean
+		id="org.hisp.dhis.caseentry.action.report.GenerateStatisticalProgramReportAction"
 		class="org.hisp.dhis.caseentry.action.report.GenerateStatisticalProgramReportAction"
 		scope="prototype">
 		<property name="selectionManager"
@@ -251,14 +252,17 @@
 		<property name="programService" ref="org.hisp.dhis.program.ProgramService" />
 		<property name="organisationUnitService"
 			ref="org.hisp.dhis.organisationunit.OrganisationUnitService" />
-		<property name="programStageInstanceService" ref="org.hisp.dhis.program.ProgramStageInstanceService" />
+		<property name="programStageInstanceService"
+			ref="org.hisp.dhis.program.ProgramStageInstanceService" />
 	</bean>
-	
-	<bean id="org.hisp.dhis.caseentry.action.report.StatisticalProgramDetailsReportAction"
+
+	<bean
+		id="org.hisp.dhis.caseentry.action.report.StatisticalProgramDetailsReportAction"
 		class="org.hisp.dhis.caseentry.action.report.StatisticalProgramDetailsReportAction"
 		scope="prototype">
 		<property name="programStageService" ref="org.hisp.dhis.program.ProgramStageService" />
-		<property name="programStageInstanceService" ref="org.hisp.dhis.program.ProgramStageInstanceService" />
+		<property name="programStageInstanceService"
+			ref="org.hisp.dhis.program.ProgramStageInstanceService" />
 		<property name="organisationUnitService"
 			ref="org.hisp.dhis.organisationunit.OrganisationUnitService" />
 		<property name="selectionManager"
@@ -273,7 +277,7 @@
 		scope="prototype">
 		<property name="dataSetService" ref="org.hisp.dhis.dataset.DataSetService" />
 	</bean>
-	
+
 	<bean
 		id="org.hisp.dhis.caseentry.action.caseaggregation.ValidationCaseAggregationAction"
 		class="org.hisp.dhis.caseentry.action.caseaggregation.ValidationCaseAggregationAction"
@@ -382,7 +386,7 @@
 		<property name="programStageInstanceService"
 			ref="org.hisp.dhis.program.ProgramStageInstanceService" />
 		<property name="selectionManager"
-            ref="org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager" />
+			ref="org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager" />
 	</bean>
 
 	<!-- Patient -->
@@ -563,7 +567,8 @@
 		<property name="patientService" ref="org.hisp.dhis.patient.PatientService" />
 		<property name="programService" ref="org.hisp.dhis.program.ProgramService" />
 		<property name="programInstanceService" ref="org.hisp.dhis.program.ProgramInstanceService" />
-		<property name="selectedStateManager" ref="org.hisp.dhis.caseentry.state.SelectedStateManager" />
+		<property name="selectedStateManager"
+			ref="org.hisp.dhis.caseentry.state.SelectedStateManager" />
 	</bean>
 
 	<bean id="org.hisp.dhis.caseentry.action.patient.ProgramEnrollmentAction"
@@ -632,11 +637,9 @@
 		<property name="patientService" ref="org.hisp.dhis.patient.PatientService" />
 		<property name="programInstanceService" ref="org.hisp.dhis.program.ProgramInstanceService" />
 	</bean>
-	
-	<bean
-		id="org.hisp.dhis.caseentry.action.patient.GetProgramAction"
-		class="org.hisp.dhis.caseentry.action.patient.GetProgramAction"
-		scope="prototype">
+
+	<bean id="org.hisp.dhis.caseentry.action.patient.GetProgramAction"
+		class="org.hisp.dhis.caseentry.action.patient.GetProgramAction" scope="prototype">
 		<property name="programService" ref="org.hisp.dhis.program.ProgramService" />
 	</bean>
 
@@ -903,71 +906,76 @@
 		<property name="tabularReportService"
 			ref="org.hisp.dhis.patientreport.PatientTabularReportService" />
 	</bean>
-	
+
 	<!-- Patient Aggregate Report -->
-	
-	<bean id="org.hisp.dhis.caseentry.action.report.GenerateAggregateReportAction"
+
+	<bean
+		id="org.hisp.dhis.caseentry.action.report.GenerateAggregateReportAction"
 		class="org.hisp.dhis.caseentry.action.report.GenerateAggregateReportAction"
 		scope="prototype">
 		<property name="programStageInstanceService"
 			ref="org.hisp.dhis.program.ProgramStageInstanceService" />
-		<property name="programStageService"
-			ref="org.hisp.dhis.program.ProgramStageService" />
-		<property name="periodService"
-			ref="org.hisp.dhis.period.PeriodService" />
-		<property name="organisationUnitService"
-			ref="org.hisp.dhis.organisationunit.OrganisationUnitService" />
+		<property name="programStageService" ref="org.hisp.dhis.program.ProgramStageService" />
+		<property name="periodService" ref="org.hisp.dhis.period.PeriodService" />
+		<property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService" />
 	</bean>
-	
-	
+
+
 	<bean id="org.hisp.dhis.caseentry.action.report.SaveAggregateReportAction"
 		class="org.hisp.dhis.caseentry.action.report.SaveAggregateReportAction"
 		scope="prototype">
 		<property name="aggregateReportService"
 			ref="org.hisp.dhis.patientreport.PatientAggregateReportService" />
-		<property name="programStageService"
-			ref="org.hisp.dhis.program.ProgramStageService" />
+		<property name="programStageService" ref="org.hisp.dhis.program.ProgramStageService" />
 		<property name="organisationUnitService"
 			ref="org.hisp.dhis.organisationunit.OrganisationUnitService" />
-		<property name="dataElementService"
-			ref="org.hisp.dhis.dataelement.DataElementService" />
-		<property name="currentUserService"
-			ref="org.hisp.dhis.user.CurrentUserService" />
+		<property name="dataElementService" ref="org.hisp.dhis.dataelement.DataElementService" />
+		<property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService" />
 	</bean>
-	
-	<bean id="org.hisp.dhis.caseentry.action.report.UpdateAggregateReportNameAction"
+
+	<bean
+		id="org.hisp.dhis.caseentry.action.report.UpdateAggregateReportNameAction"
 		class="org.hisp.dhis.caseentry.action.report.UpdateAggregateReportNameAction"
 		scope="prototype">
 		<property name="aggregateReportService"
 			ref="org.hisp.dhis.patientreport.PatientAggregateReportService" />
 	</bean>
-	
-	<bean id="org.hisp.dhis.caseentry.action.report.DeleteAggregateReportAction"
+
+	<bean
+		id="org.hisp.dhis.caseentry.action.report.DeleteAggregateReportAction"
 		class="org.hisp.dhis.caseentry.action.report.DeleteAggregateReportAction"
 		scope="prototype">
 		<property name="aggregateReportService"
 			ref="org.hisp.dhis.patientreport.PatientAggregateReportService" />
 	</bean>
-	
-	<bean id="org.hisp.dhis.caseentry.action.report.GetAggregateReportListAction"
+
+	<bean
+		id="org.hisp.dhis.caseentry.action.report.GetAggregateReportListAction"
 		class="org.hisp.dhis.caseentry.action.report.GetAggregateReportListAction"
 		scope="prototype">
 		<property name="aggregateReportService"
 			ref="org.hisp.dhis.patientreport.PatientAggregateReportService" />
 		<property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService" />
 	</bean>
-	
+
 	<bean id="org.hisp.dhis.caseentry.action.report.GetAggregateReportAction"
 		class="org.hisp.dhis.caseentry.action.report.GetAggregateReportAction"
 		scope="prototype">
 		<property name="aggregateReportService"
 			ref="org.hisp.dhis.patientreport.PatientAggregateReportService" />
-		<property name="dataElementService"
-			ref="org.hisp.dhis.dataelement.DataElementService" />
+		<property name="dataElementService" ref="org.hisp.dhis.dataelement.DataElementService" />
+	</bean>
+
+	<bean
+		id="org.hisp.dhis.caseentry.action.report.GetOrganisationUnitsByGroupAction"
+		class="org.hisp.dhis.caseentry.action.report.GetOrganisationUnitsByGroupAction"
+		scope="prototype">
+		<property name="organisationUnitGroupService"
+			ref="org.hisp.dhis.organisationunit.OrganisationUnitGroupService" />
 	</bean>
 
 	<!-- Reminder -->
-	
+
 	<bean
 		id="org.hisp.dhis.caseentry.action.reminder.GetProgramTrackingListAction"
 		class="org.hisp.dhis.caseentry.action.reminder.GetProgramTrackingListAction"
@@ -1022,7 +1030,8 @@
 		<property name="programInstanceService" ref="org.hisp.dhis.program.ProgramInstanceService" />
 		<property name="patientAuditService" ref="org.hisp.dhis.patient.PatientAuditService" />
 		<property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService" />
-		<property name="patientAttributeService" ref="org.hisp.dhis.patient.PatientAttributeService" />
+		<property name="patientAttributeService"
+			ref="org.hisp.dhis.patient.PatientAttributeService" />
 	</bean>
 
 	<!-- Comment -->
@@ -1035,10 +1044,12 @@
 		<property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService" />
 	</bean>
 
-	<bean id="org.hisp.dhis.caseentry.action.reminder.RemovePatientCommentAction"
+	<bean
+		id="org.hisp.dhis.caseentry.action.reminder.RemovePatientCommentAction"
 		class="org.hisp.dhis.caseentry.action.reminder.RemovePatientCommentAction"
 		scope="prototype">
-		<property name="commentService" ref="org.hisp.dhis.patientcomment.PatientCommentService" />
+		<property name="commentService"
+			ref="org.hisp.dhis.patientcomment.PatientCommentService" />
 		<property name="programStageInstanceService"
 			ref="org.hisp.dhis.program.ProgramStageInstanceService" />
 	</bean>

=== 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-01-17 12:54:38 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/resources/org/hisp/dhis/caseentry/i18n_module.properties	2013-01-21 06:18:31 +0000
@@ -523,8 +523,6 @@
 period_range = Date range
 select_only_one_period = Please select only one period
 position = Position
-select_only_one_data_element = Please select only one data element
-select_data_element_for_grouping = Please select a data element for grouping
 pdf = PDF
 csv = CSV
 rows = Rows
@@ -540,5 +538,7 @@
 select_from_date = Select from date
 select_to_date = Select to date
 user_orgunit = User organisation unit
-user_orgunit_children = Organisation unit chilren
-
+user_orgunit_children = User organisation unit chilren
+auto_select_orgunit_by = Auto-select organisation units by
+like = LIKE
+in = IN
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/resources/struts.xml'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/resources/struts.xml	2013-01-16 08:41:28 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/resources/struts.xml	2013-01-21 06:18:31 +0000
@@ -933,6 +933,12 @@
             <param name="requiredAuthorities">F_GENERATE_BENEFICIARY_TABULAR_REPORT</param>
 		</action>
 		
+		<action name="getOrganisationUnitPathsByGroup"
+			class="org.hisp.dhis.caseentry.action.report.GetOrganisationUnitsByGroupAction">
+			<result name="success" type="velocity-json">
+				/dhis-web-caseentry/jsonminOrganisationUnitPaths.vm</result>
+		</action>
+		
 		<!-- SMS Reminder -->
 
 		<action name="smsReminderSelect"

=== modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/app/app.js'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/app/app.js	2013-01-17 12:54:38 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/app/app.js	2013-01-21 06:18:31 +0000
@@ -10,7 +10,7 @@
 				};
 				obj.system.rootnodes = [];
 				for (var i = 0; i < r.user.ous.length; i++) {
-					obj.system.rootnodes.push({id: r.user.ous[i].id, text: r.user.ous[i].name, leaf: r.user.ous[i].leaf});
+					obj.system.rootnodes.push({id: r.user.ous[i].id, localid: r.user.ous[i].id,text: r.user.ous[i].name, leaf: r.user.ous[i].leaf});
 				}
 				
 				obj.system.program = [];
@@ -43,6 +43,7 @@
 			programstages_get: 'loadReportProgramStages.action',
 			dataelements_get: 'loadDataElements.action',
 			organisationunitchildren_get: 'getOrganisationUnitChildren.action',
+			organisationunit_getbygroup: 'getOrganisationUnitPathsByGroup.action',
 			generatetabularreport_get: 'generateTabularReport.action',
 			casebasedfavorite_getall: 'getTabularReports.action',
 			casebasedfavorite_get: 'getTabularReport.action',
@@ -93,6 +94,9 @@
         data: {
 			domain: 'domain_',
 		},
+		root: {
+			id: 'root'
+		},
 		download: {
             xls: 'xls',
 			pdf: 'pdf',
@@ -164,7 +168,18 @@
         window_confirm_width: 250,
 		window_record_width: 450,
 		window_record_height: 300
-    }
+    },
+	util: {
+		jsonEncodeString: function(str) {
+			return typeof str === 'string' ? str.replace(/[^a-zA-Z 0-9(){}<>_!+;:?*&%#-]+/g,'') : str;
+		},
+		jsonEncodeArray: function(a) {
+			for (var i = 0; i < a.length; i++) {
+				a[i] = DV.conf.util.jsonEncodeString(a[i]);
+			}
+			return a;
+		}
+	}
 };
 
 Ext.Loader.setConfig({enabled: true});
@@ -440,6 +455,8 @@
 					params.queryMode = 'remote';
 					params.valueField = 'o';
 					params.displayField = 'o';
+					params.multiSelect = true;
+					params.delimiter = ';';
 					params.store = Ext.create('Ext.data.Store', {
 						fields: ['o'],
 						data:[],
@@ -467,10 +484,10 @@
 				params.value = '=';
 				
 				if(valueType == 'string' || valueType == 'trueOnly' 
-					|| valueType == 'bool' && valueType != 'list' ){
+					|| valueType == 'bool' || valueType == 'list' ){
 					params.store = new Ext.data.ArrayStore({
 						fields: ['value','name'],
-						data: [ ['=','='] ]
+						data: [ ['=','='],['like',TR.i18n.like],['in',TR.i18n.in] ]
 					});
 				}
 				else
@@ -825,7 +842,7 @@
 								}});
 							}
 						});  
-                },
+					},
 					updateName: function(name) {
 						if (TR.store.caseBasedFavorite.findExact('name', name) != -1) {
 							return;
@@ -881,8 +898,13 @@
 								Ext.getCmp('endDate').setValue( f.endDate );
 								Ext.getCmp('facilityLBCombobox').setValue( f.facilityLB );
 								Ext.getCmp('levelCombobox').setValue( f.level );
+								
 								TR.state.orgunitIds = f.orgunitIds;
 								
+								/* for (var i = 0; i < f.orgunitIds.length; i++) {
+									TR.cmp.params.organisationunit.records.push({id: f.organisationUnits[i].id, name: TR.conf.util.jsonEncodeString(f.organisationUnits[i].name)});
+								} */
+								
 								// Data element
 								TR.cmp.params.dataelement.objects = [];
 								TR.store.dataelement.selected.removeAll();
@@ -1018,8 +1040,14 @@
 								
 								// Orgunits
 								
-								TR.cmp.params.organisationunit.treepanel.getSelectionModel().deselectAll();
-								TR.state.orgunitIds = f.orgunitIds;
+								var treepanel = TR.cmp.params.organisationunit.treepanel;
+								treepanel.getSelectionModel().deselectAll();
+								TR.state.orgunitIds = [];
+								treepanel.numberOfRecords = f.orgunitIds.length;
+								for (var i = 0; i < f.orgunitIds.length; i++) {
+									treepanel.multipleExpand(f.orgunitIds[i].id, f.orgunitIds[i].path);
+									TR.state.orgunitIds.push( f.orgunitIds[i].localid );
+								}
 								
 								// Selected data elements
 								
@@ -1067,9 +1095,7 @@
 								TR.util.positionFilter.convert( f.position );
 								Ext.getCmp('dataElementGroupByCbx').setValue( f.deGroupBy );
 								Ext.getCmp('aggregateType').setValue( f.deGroupBy );
-																
 								Ext.getCmp('levelCombobox').setValue( f.level );
-								TR.state.orgunitIds = f.orgunitIds;
 																
 								// Program stage									
 								var storeProgramStage = TR.store.programStage;
@@ -1423,7 +1449,7 @@
 				p.currentPage = this.currentPage;
 				
 				// organisation unit
-				p.orgunitIds = TR.state.orgunitIds;
+				 p.orgunitIds = TR.state.orgunitIds;
 				
 				// Get searching values
 				p.searchingValues = [];
@@ -1462,6 +1488,7 @@
 				p += "&programStageId=" + TR.cmp.params.programStage.getValue();
 				
 				// organisation units
+				
 				for( var i=0; i<TR.state.orgunitIds.length; i++ ){
 					p += '&orgunitIds=' + TR.state.orgunitIds[i];
 				}
@@ -1593,10 +1620,10 @@
 						return false;
 					}
 				
-					if (TR.state.orgunitIds.length == 0) {
+					/* if (TR.state.orgunitIds.length == 0) {
 						TR.util.notification.error(TR.i18n.et_no_orgunits, TR.i18n.em_no_orgunits);
 						return false;
-					}
+					} */
 					
 					if (Ext.getCmp('programStageCombobox').getValue() == '') {
 						TR.util.notification.error(TR.i18n.em_no_program_stage, TR.i18n.em_no_program_stage);
@@ -1736,32 +1763,57 @@
 				var p = {};
 				p.programStageId = TR.cmp.params.programStage.getValue();
 				p.aggregateType = Ext.getCmp('aggregateType').getValue().aggregateType;
+				
+				// orgunits
+				
+				// p.orgunitIds = TR.state.orgunitIds;
 				p.orgunitIds = TR.state.orgunitIds;
+								
+				p.userOrganisationUnit = TR.cmp.aggregateFavorite.userorganisationunit.getValue();
+				p.userOrganisationUnitChildren = TR.cmp.aggregateFavorite.userorganisationunitchildren.getValue();
+				
 				p.limitRecords = Ext.getCmp('limitOption').getValue();
 				
 				var position = TR.state.aggregateReport.getPosition();
-				if( TR.cmp.settings.dataElementGroupBy.getValue() != null ){
-					p.deGroupBy = TR.cmp.settings.dataElementGroupBy.getValue().split('_')[1];
+				if( Ext.getCmp('dataElementGroupByCbx').getValue() != null ){
+					p.deGroupBy = Ext.getCmp('dataElementGroupByCbx').getValue().split('_')[1];
 				}
 				
 				// Filter values
 				
 				p.deFilters = [];
 				TR.cmp.params.dataelement.selected.store.each( function(r) {
+					var valueType = r.data.valueType;
 					var deId = r.data.id;
 					var filterOpt = Ext.getCmp('filter_opt_' + deId).rawValue;
 					var filterValue = Ext.getCmp('filter_' + deId).rawValue;
-					var filter = deId.split('_')[1] + "_" + filterOpt + "_" + filterValue;
+					var filter = deId.split('_')[1] + "_" + filterOpt + '_';
 					
-					var valueType = r.data.valueType;
-					if( valueType != 'string' && valueType != 'trueOnly' 
-						&& valueType != 'bool' && valueType != 'list')
-						{
-							var deId = deId + '_1';
+					if( valueType == 'string' || valueType == 'trueOnly' 
+						|| valueType == 'bool' || valueType == 'list' )
+					{
+						var filterValues = filterValue.split(";");
+						filter +=" (";
+						for(var i=0;i<filterValues.length;i++)
+						{
+							filter += "'"+ filterValues[i] +"',";
+						}
+						filter = filter.substr(0,filter.length - 1) + " ) ";
+					}
+					else 
+					{
+						filter += filterValue;
+						
+						var deId = deId + '_1';
+						if( Ext.getCmp('filter_' + deId) != undefined
+							&& Ext.getCmp('filter_' + deId).rawValue != '' )
+						{
 							filterOpt = Ext.getCmp('filter_opt_' + deId).rawValue;
 							filterValue = Ext.getCmp('filter_' + deId).rawValue;
 							filter += "_" + filterOpt + "_" + filterValue;
 						}
+					
+					}
 					p.deFilters.push( filter );
 					
 				});
@@ -1888,10 +1940,12 @@
 						return false;
 					}
 				
-					if (TR.state.orgunitIds.length == 0) {
+					/* if (TR.state.orgunitIds.length == 0 
+						&& TR.cmp.aggregateFavorite.userorganisationunit.getValue() == 'false'
+						&& TR.cmp.aggregateFavorite.userorganisationunitchildren.getValue() == 'false' ) {
 						TR.util.notification.error(TR.i18n.et_no_orgunits, TR.i18n.em_no_orgunits);
 						return false;
-					}
+					}*/ 
 					
 					if (Ext.getCmp('programStageCombobox').getValue() == '') {
 						TR.util.notification.error(TR.i18n.em_no_program_stage, TR.i18n.em_no_program_stage);
@@ -1947,19 +2001,6 @@
 						return false;
 					}
 					
-					var position = TR.state.aggregateReport.getPosition();
-					if( position == TR.conf.reportPosition.POSITION_ROW_DATA
-						&& TR.cmp.params.dataelement.selected.store.data.items.length == 0) {
-						TR.util.notification.error(TR.i18n.em_no_dataelement, TR.i18n.em_no_dataelement);
-						return false;
-					};
-					
-					if( position==TR.conf.reportPosition.POSITION_ROW_DATA 
-						&& TR.cmp.settings.dataElementGroupBy.getValue()=='' ){
-						TR.util.notification.error(TR.i18n.select_data_element_for_grouping, TR.i18n.select_data_element_for_grouping);
-						return false;
-					}
-					
 					return true;
 				},
 				response: function(r) {
@@ -2240,6 +2281,12 @@
 			params.menuFilterText = TR.value.filter;
 			params.sortable = false;
 			params.draggable = true;
+			
+			if(Ext.getCmp('reportTypeGroup').getValue().reportType=='false')
+			{
+				params.menuDisabled = true;
+				params.draggable = false;
+			}
 			params.isEditAllowed = true;
 			params.compulsory = compulsory;
 			
@@ -2486,7 +2533,7 @@
 									id: 'reportTypeGroup',
 									fieldLabel: TR.i18n.report_type,
 									labelStyle: 'font-weight:bold',
-									labelAlign: 'top',
+									//labelAlign: 'top',
 									columns: 2,
 									vertical: true,
 									items: [
@@ -2504,10 +2551,12 @@
 													Ext.getCmp('aggregateType').setVisible(false);
 													Ext.getCmp('downloadPdfIcon').setVisible(false);
 													Ext.getCmp('downloadCvsIcon').setVisible(false);
+													Ext.getCmp('positionField').setVisible(false);
+													Ext.getCmp('completedEventsOpt').setVisible(false);
 													Ext.getCmp('aggregateFavoriteBtn').setVisible(false);
+													Ext.getCmp('datePeriodRangeDiv').setVisible(false);
 													Ext.getCmp('caseBasedFavoriteBtn').setVisible(true);
 													Ext.getCmp('levelCombobox').setVisible(true);
-													Ext.getCmp('datePeriodRangeDiv').setVisible(false);
 													
 													Ext.getCmp('dateRangeDiv').setVisible(true);
 													Ext.getCmp('relativePeriodsDiv').setVisible(false); 
@@ -2534,8 +2583,10 @@
 													Ext.getCmp('downloadCvsIcon').setVisible(true);
 													Ext.getCmp('aggregateFavoriteBtn').setVisible(true);
 													Ext.getCmp('caseBasedFavoriteBtn').setVisible(false);
+													Ext.getCmp('positionField').setVisible(true);
+													Ext.getCmp('completedEventsOpt').setVisible(true);
+													Ext.getCmp('dateRangeDiv').setVisible(false);
 													Ext.getCmp('levelCombobox').setVisible(false);
-													Ext.getCmp('dateRangeDiv').setVisible(false);
 													
 													Ext.getCmp('datePeriodRangeDiv').setVisible(true);
 													Ext.getCmp('fixedPeriodsDiv').setVisible(true);
@@ -2643,7 +2694,7 @@
 								activeOnTop: true,
 								cls: 'tr-accordion',
 								bodyStyle: 'border:0 none',
-								height: 430,
+								height: 475,
 								items: [
 							
 									// DATE-RANGE
@@ -2790,9 +2841,10 @@
 												}
 											},
 											Ext.create('Ext.grid.Panel', {
-												style: 'border: solid 2px #D0D0D0',
+												style: 'border: solid 1px #D0D0D0',
 												width: TR.conf.layout.west_fieldset_width - 18,
 												store: TR.store.dateRange,
+												height: 205,
 												columns: [
 													{ 
 														text: TR.i18n.start_date,  
@@ -2823,8 +2875,7 @@
 															}
 														}]
 													}
-												],
-												height: 130,
+												]
 											})
 										]
 									},
@@ -3075,7 +3126,7 @@
 														name: 'availableFixedPeriods',
 														cls: 'tr-toolbar-multiselect-left',
 														width: (TR.conf.layout.west_fieldset_width - TR.conf.layout.west_width_subtractor) / 2,
-														height: 180,
+														height: 245,
 														valueField: 'id',
 														displayField: 'name',
 														store: TR.store.fixedperiod.available,
@@ -3120,7 +3171,7 @@
 														name: 'selectedFixedPeriods',
 														cls: 'tr-toolbar-multiselect-right',
 														width: (TR.conf.layout.west_fieldset_width - TR.conf.layout.west_width_subtractor) / 2,
-														height: 180,
+														height: 245,
 														displayField: 'name',
 														valueField: 'id',
 														ddReorder: false,
@@ -3212,6 +3263,7 @@
 														handler: function(chb, checked) {
 															TR.cmp.params.organisationunit.toolbar.xable(checked, TR.cmp.aggregateFavorite.userorganisationunitchildren.getValue());
 															TR.cmp.params.organisationunit.treepanel.xable(checked, TR.cmp.aggregateFavorite.userorganisationunitchildren.getValue());
+															TR.state.orgunitIds = [];
 														},
 														listeners: {
 															added: function() {
@@ -3225,71 +3277,225 @@
 														boxLabel: TR.i18n.user_orgunit_children,
 														labelWidth: TR.conf.layout.form_label_width,
 														handler: function(chb, checked) {
-															TR.cmp.params.organisationunit.toolbar.xable(checked, TR.cmp.favorite.userorganisationunit.getValue());
-															TR.cmp.params.organisationunit.treepanel.treepanel.xable(checked, TR.cmp.favorite.userorganisationunit.getValue());
+															TR.cmp.params.organisationunit.toolbar.xable(checked, TR.cmp.aggregateFavorite.userorganisationunit.getValue());
+															TR.cmp.params.organisationunit.treepanel.xable(checked, TR.cmp.aggregateFavorite.userorganisationunit.getValue());
 														},
 														listeners: {
 															added: function() {
 																TR.cmp.aggregateFavorite.userorganisationunitchildren = this;
+															},
+															handler: function(chb, checked) {
+																TR.cmp.params.organisationunit.toolbar.xable(checked, TR.cmp.aggregateFavorite.userorganisationunitchildren.getValue());
+																TR.cmp.params.organisationunit.treepanel.xable(checked, TR.cmp.aggregateFavorite.userorganisationunitchildren.getValue());
+																TR.state.orgunitIds = [];
+															},
+														}
+													}
+												]
+											},
+											{
+												xtype: 'toolbar',
+												id: 'organisationunit_t',
+												style: 'margin-bottom: 5px',
+												width: TR.conf.layout.west_fieldset_width - 18,
+												xable: function(checked, value) {
+													if (checked || value) {
+														this.disable();
+													}
+													else {
+														this.enable();
+													}
+												},
+												defaults: {
+													height: 24
+												},
+												items: [
+													{
+														xtype: 'label',
+														text: 'Auto-select organisation units by',
+														style: 'padding-left:8px; color:#666; line-height:24px'
+													},
+													'->',
+													{
+														text: 'Group..',
+														handler: function() {},
+														listeners: {
+															added: function() {
+																this.menu = Ext.create('Ext.menu.Menu', {
+																	shadow: false,
+																	showSeparator: false,
+																	width: TR.conf.layout.treepanel_toolbar_menu_width_group,
+																	items: [
+																		{
+																			xtype: 'grid',
+																			cls: 'tr-menugrid',
+																			width: TR.conf.layout.treepanel_toolbar_menu_width_group,
+																			scroll: 'vertical',
+																			columns: [
+																				{
+																					dataIndex: 'name',
+																					width: TR.conf.layout.treepanel_toolbar_menu_width_group,
+																					style: 'display:none'
+																				}
+																			],
+																			setHeightInMenu: function(store) {
+																				var h = store.getCount() * 16,
+																					sh = TR.util.viewport.getSize().y * 0.4;
+																				this.setHeight(h > sh ? sh : h);
+																				this.doLayout();
+																				this.up('menu').doLayout();
+																			},
+																			store: TR.store.orgunitGroup,
+																			listeners: {
+																				itemclick: function(g, r) {
+																					g.getSelectionModel().select([], false);
+																					this.up('menu').hide();
+																					TR.cmp.params.organisationunit.treepanel.selectByGroup(r.data.id);
+																				}
+																			}
+																		}
+																	],
+																	listeners: {
+																		show: function() {
+																			if (!TR.store.orgunitGroup.isloaded) {
+																				TR.store.orgunitGroup.load({scope: this, callback: function() {
+																					this.down('grid').setHeightInMenu(TR.store.orgunitGroup);
+																				}});
+																			}
+																			else {
+																				this.down('grid').setHeightInMenu(TR.store.orgunitGroup);
+																			}
+																		}
+																	}
+																});
 															}
 														}
 													}
-												]
+												],
+												listeners: {
+													added: function() {
+														TR.cmp.params.organisationunit.toolbar = this;
+													}
+												}
 											},
 											{
 												xtype: 'treepanel',
+												id: 'treeOrg',
 												cls: 'tr-tree',
-												id: 'treeOrg',
 												width: TR.conf.layout.west_fieldset_width - TR.conf.layout.west_width_subtractor,
+												rootVisible: false,
 												autoScroll: true,
 												multiSelect: true,
-												isrendered: false,
-												storage: {},
-												addToStorage: function(objects) {
-													for (var i = 0; i < objects.length; i++) {
-														this.storage[objects[i].id] = objects[i];
-													}
-												},
-												selectRoot: function() {
-													if (this.isrendered) {
-														if (!this.getSelectionModel().getSelection().length) {
-															this.getSelectionModel().select(this.getRootNode());
+												rendered: false,
+												selectRootIf: function() {
+													if (this.getSelectionModel().getSelection().length < 1) {
+														var node = this.getRootNode().findChild('id', TR.init.system.rootnodes[0].id, true);
+														if (this.rendered) {
+															this.getSelectionModel().select(node);
 														}
-													}
-												},
-												findNameById: function(id) {
-													var name = this.store.getNodeById(id) ? this.store.getNodeById(id).data.text : null;
-													if (!name) {
-														for (var k in this.storage) {
-															if (k == id) {
-																name = this.storage[k].name;
+														return node;
+													}
+												},
+												numberOfRecords: 0,
+												recordsToSelect: [],
+												multipleSelectIf: function() {
+													if (this.recordsToSelect.length === this.numberOfRecords) {
+														this.getSelectionModel().select(this.recordsToSelect);
+														this.recordsToSelect = [];
+														this.numberOfRecords = 0;
+													}
+												},
+												multipleExpand: function(id, path) {
+													this.expandPath('/' + TR.conf.finals.root.id + path, 'id', '/', function() {
+														var record = this.getRootNode().findChild('id', id, true);
+														this.recordsToSelect.push(record);
+														this.multipleSelectIf();
+													}, this);
+												},
+												select: function(url, params) {
+													if (!params) {
+														params = {};
+													}
+													Ext.Ajax.request({
+														url: url,
+														method: 'GET',
+														params: params,
+														scope: this,
+														success: function(r) {
+															var a = Ext.JSON.decode(r.responseText).organisationUnits;
+															this.numberOfRecords = a.length;
+															for (var i = 0; i < a.length; i++) {
+																this.multipleExpand(a[i].id, a[i].path);
 															}
 														}
-													}
-													return name;
+													});
+												},
+												selectByGroup: function(id) {
+													if (id) {
+														var url = TR.conf.finals.ajax.path_root + TR.conf.finals.ajax.organisationunit_getbygroup,
+															params = {id: id};
+														this.select(url, params);
+													}
+												},
+												selectByLevel: function(level) {
+													if (level) {
+														var url = TR.conf.finals.ajax.path_root + TR.conf.finals.ajax.organisationunit_getbylevel,
+															params = {level: level};
+														this.select(url, params);
+													}
+												},
+												selectByIds: function(ids) {
+													if (ids) {
+														var url = TR.conf.finals.ajax.path_root + TR.conf.finals.ajax.organisationunit_getbyids;
+														Ext.Array.each(ids, function(item) {
+															url = Ext.String.urlAppend(url, 'ids=' + item);
+														});
+														if (!this.rendered) {
+															TR.cmp.params.organisationunit.panel.expand();
+														}
+														this.select(url);
+													}
 												},
 												store: Ext.create('Ext.data.TreeStore', {
+													fields: ['id', 'localid', 'text'],
 													proxy: {
 														type: 'ajax',
 														url: TR.conf.finals.ajax.path_root + TR.conf.finals.ajax.organisationunitchildren_get
 													},
 													root: {
-														id: 0,
+														id: TR.conf.finals.root.id,
+														localid: '0',
                                                         text: "/",
 														expanded: true,
 														children: TR.init.system.rootnodes
+													},
+													listeners: {
+														load: function(s, node, r) {
+															for (var i = 0; i < r.length; i++) {
+																r[i].data.text = TR.conf.util.jsonEncodeString(r[i].data.text);
+															}
+														}
 													}
 												}),
-												rootVisible: false, 
+												xable: function(checked, value) {
+													if (checked || value) {
+														this.disable();
+													}
+													else {
+														this.enable();
+													}
+												},
 												listeners: {
 													added: function() {
 														TR.cmp.params.organisationunit.treepanel = this;
 													},
-													afterrender: function( treePanel, eOpts )
-													{
+													render: function() {
+														this.rendered = true;
+													},
+													afterrender: function( treePanel, eOpts ){
 														treePanel.getSelectionModel().select( treePanel.getRootNode() );
 														TR.state.orgunitIds = [];
-														var orgunitid = treePanel.getSelectionModel().getSelection()[0].data.id;
+														var orgunitid = treePanel.getSelectionModel().getSelection()[0].data.localid;
 														if(orgunitid==0){
 															for( var i in TR.init.system.rootnodes){
 																 TR.state.orgunitIds.push( TR.init.system.rootnodes[i].id );
@@ -3303,8 +3509,37 @@
 														TR.state.orgunitIds = [];
 														var selectedNodes = TR.cmp.params.organisationunit.treepanel.getSelectionModel().getSelection();
 														for( var i=0; i<selectedNodes.length; i++ ){
-															TR.state.orgunitIds.push( selectedNodes[i].data.id);
-														}
+															TR.state.orgunitIds.push( selectedNodes[i].data.localid);
+														}
+													},
+													itemcontextmenu: function(v, r, h, i, e) {
+														v.getSelectionModel().select(r, false);
+
+														if (v.menu) {
+															v.menu.destroy();
+														}
+														v.menu = Ext.create('Ext.menu.Menu', {
+															id: 'treepanel-contextmenu',
+															showSeparator: false
+														});
+														if (!r.data.leaf) {
+															v.menu.add({
+																id: 'treepanel-contextmenu-item',
+																text: TR.i18n.select_all_children,
+																icon: 'images/node-select-child.png',
+																handler: function() {
+																	r.expand(false, function() {
+																		v.getSelectionModel().select(r.childNodes, true);
+																		v.getSelectionModel().deselect(r);
+																	});
+																}
+															});
+														}
+														else {
+															return;
+														}
+
+														v.menu.showAt(e.xy);
 													}
 												}
 											}
@@ -3314,7 +3549,7 @@
 												TR.cmp.params.organisationunit.panel = this;
 											},
 											expand: function() {
-												TR.cmp.params.organisationunit.treepanel.setHeight(TR.cmp.params.organisationunit.panel.getHeight() - TR.conf.layout.west_fill_accordion_organisationunit - 25 );
+												TR.cmp.params.organisationunit.treepanel.setHeight(TR.cmp.params.organisationunit.panel.getHeight() - TR.conf.layout.west_fill_accordion_organisationunit - 60 );
 											}
 										}
 									},
@@ -3571,7 +3806,7 @@
 														id: 'filterPanel',
 														bodyStyle: 'background-color:transparent; padding:10px 10px 0px 3px',
 														autoScroll: true,
-														height: 65,
+														height: 110,
 														width: (TR.conf.layout.west_fieldset_width - TR.conf.layout.west_width_subtractor) ,
 														items: []
 													}
@@ -3592,38 +3827,9 @@
 										cls: 'tr-accordion-options',
 										items: [
 											{
-												xtype: 'combobox',
-												cls: 'tr-combo',
-												id: 'facilityLBCombobox',
-												fieldLabel: TR.i18n.use_data_from_level,
-												labelWidth: 135,
-												emptyText: TR.i18n.please_select,
-												queryMode: 'local',
-												editable: false,
-												valueField: 'value',
-												displayField: 'name',
-												width: TR.conf.layout.west_fieldset_width - TR.conf.layout.west_width_subtractor,
-												store:  new Ext.data.ArrayStore({
-													fields: ['value', 'name'],
-													data: [['all', TR.i18n.all], ['childrenOnly', TR.i18n.children_only], ['selected', TR.i18n.selected]],
-												}),
-												value: 'all',
-												listeners: {
-													added: function() {
-														TR.cmp.settings.facilityLB = this;
-													}
-												}
-											},
-											{
-												xtype: 'checkbox',
-												id: 'completedEventsOpt',
-												style:'padding: 5px 0px 5px 15px;',
-												boxLabel: TR.i18n.use_completed_events,
-												boxLabelAlign: 'before'
-											},
-											{
 												xtype: 'fieldset',
 												title: TR.i18n.position,
+												id: 'positionField',
 												layout: 'anchor',
 												collapsible: false,
 												collapsed: false,
@@ -3657,15 +3863,6 @@
 															},
 															change: function (cb, nv, ov) {
 																TR.util.positionFilter.orgunit();
-																var position = TR.state.aggregateReport.getPosition();
-																if( position!=TR.conf.reportPosition.POSITION_ROW_DATA){
-																	Ext.getCmp('dataElementGroupByCbx').disable();
-																	Ext.getCmp('limitOption').disable();
-																}
-																else{
-																	Ext.getCmp('dataElementGroupByCbx').enable();
-																	Ext.getCmp('limitOption').enable();
-																}
 															}
 														}
 													},
@@ -3694,15 +3891,6 @@
 															},
 															change: function (cb, nv, ov) {
 																TR.util.positionFilter.period();
-																var position = TR.state.aggregateReport.getPosition();
-																if( position!=TR.conf.reportPosition.POSITION_ROW_DATA){
-																	Ext.getCmp('dataElementGroupByCbx').disable();
-																	Ext.getCmp('limitOption').disable();
-																}
-																else{
-																	Ext.getCmp('dataElementGroupByCbx').enable();
-																	Ext.getCmp('limitOption').enable();
-																}
 															}
 														}
 													},
@@ -3726,17 +3914,6 @@
 														listeners: {
 															added: function() {
 																TR.cmp.settings.positionData = this;
-															},
-															change: function (cb, nv, ov) {
-																var position = TR.state.aggregateReport.getPosition();
-																if( position!=TR.conf.reportPosition.POSITION_ROW_DATA){
-																	Ext.getCmp('dataElementGroupByCbx').disable();
-																	Ext.getCmp('limitOption').disable();
-																}
-																else{
-																	Ext.getCmp('dataElementGroupByCbx').enable();
-																	Ext.getCmp('limitOption').enable();
-																}
 															}
 														}
 													}
@@ -3777,6 +3954,37 @@
 													}]
 												},
 												{
+													xtype: 'checkbox',
+													id: 'completedEventsOpt',
+													style:'padding: 0px 0px 0px 3px;',
+													boxLabel: TR.i18n.use_completed_events,
+													boxLabelAlign: 'before',
+													labelWidth: 135,
+												},
+												{
+													xtype: 'combobox',
+													cls: 'tr-combo',
+													id: 'facilityLBCombobox',
+													fieldLabel: TR.i18n.use_data_from_level,
+													labelWidth: 135,
+													emptyText: TR.i18n.please_select,
+													queryMode: 'local',
+													editable: false,
+													valueField: 'value',
+													displayField: 'name',
+													width: TR.conf.layout.west_fieldset_width - TR.conf.layout.west_width_subtractor - 40,
+													store:  new Ext.data.ArrayStore({
+														fields: ['value', 'name'],
+														data: [['all', TR.i18n.all], ['childrenOnly', TR.i18n.children_only], ['selected', TR.i18n.selected]],
+													}),
+													value: 'all',
+													listeners: {
+														added: function() {
+															TR.cmp.settings.facilityLB = this;
+														}
+													}
+												},
+												{
 													xtype: 'combobox',
 													cls: 'tr-combo',
 													id:'levelCombobox',
@@ -3789,7 +3997,7 @@
 													editable: false,
 													valueField: 'value',
 													displayField: 'name',
-													width: TR.conf.layout.west_fieldset_width - TR.conf.layout.west_width_subtractor - 30,
+													width: TR.conf.layout.west_fieldset_width - TR.conf.layout.west_width_subtractor - 40,
 													store: Ext.create('Ext.data.Store', {
 														fields: ['value', 'name'],
 														data: TR.init.system.level,
@@ -3810,10 +4018,9 @@
 													emptyText: TR.i18n.please_select,
 													queryMode: 'local',
 													editable: true,
-													disabled: true,
 													valueField: 'id',
 													displayField: 'name',
-													width: TR.conf.layout.west_fieldset_width - TR.conf.layout.west_width_subtractor - 30,
+													width: TR.conf.layout.west_fieldset_width - TR.conf.layout.west_width_subtractor - 40,
 													store: TR.store.dataelement.available,
 													listeners: {
 														added: function() {
@@ -3829,7 +4036,6 @@
 													labelWidth: 135,
 													editable: true,
 													allowBlank:true,
-													disabled: true,
 													width: TR.conf.layout.west_fieldset_width - TR.conf.layout.west_width_subtractor - 30,
 													minValue: 1,
 													listeners: {

=== modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/i18n.vm'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/i18n.vm	2013-01-17 08:06:51 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/i18n.vm	2013-01-21 06:18:31 +0000
@@ -128,7 +128,6 @@
 em_no_period: '$encoder.jsEscape($i18n.getString( 'em_no_period' ) , "'")',
 period_range: '$encoder.jsEscape($i18n.getString( 'period_range' ) , "'")',
 select_only_one_period: '$encoder.jsEscape($i18n.getString( 'select_only_one_period' ) , "'")',
-select_only_one_data_element: '$encoder.jsEscape($i18n.getString( 'select_only_one_data_element' ) , "'")',
 position: '$encoder.jsEscape($i18n.getString( 'position' ) , "'")',
 orgunit: '$encoder.jsEscape($i18n.getString( 'orgunit' ) , "'")',
 data: '$encoder.jsEscape($i18n.getString( 'data' ) , "'")',
@@ -149,5 +148,10 @@
 show_hide_filter_values: '$encoder.jsEscape($i18n.getString( 'show_hide_filter_values' ) , "'")',
 date_period_range: '$encoder.jsEscape($i18n.getString( 'date_period_range' ) , "'")',
 select_from_date: '$encoder.jsEscape($i18n.getString( 'select_from_date' ) , "'")',
-select_to_date: '$encoder.jsEscape($i18n.getString( 'select_to_date' ) , "'")'
+select_to_date: '$encoder.jsEscape($i18n.getString( 'select_to_date' ) , "'")',
+user_orgunit: '$encoder.jsEscape($i18n.getString( 'user_orgunit' ) , "'")',
+user_orgunit_children: '$encoder.jsEscape($i18n.getString( 'user_orgunit_children' ) , "'")',
+auto_select_orgunit_by: '$encoder.jsEscape($i18n.getString( 'auto_select_orgunit_by' ) , "'")',
+in: '$encoder.jsEscape($i18n.getString( 'in' ) , "'")',
+like: '$encoder.jsEscape($i18n.getString( 'like' ) , "'")',
 };
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/jsonTabularAggregateReport.vm'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/jsonTabularAggregateReport.vm	2013-01-16 08:41:28 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/jsonTabularAggregateReport.vm	2013-01-21 06:18:31 +0000
@@ -35,7 +35,11 @@
 		#set( $size = $aggregateReport.organisationUnits.size() )
 		#set( $organisationUnits = ${aggregateReport.organisationUnits} )
 		#foreach( ${organisationUnit} in $!{organisationUnits} )
-			$organisationUnit.id
+			{
+				"id": "$organisationUnit.uid",
+				"localid": "$organisationUnit.id",
+				"path":"#foreach($anc in $organisationUnit.getAncestors())/${anc.uid}#end"
+			}
 			#if( $velocityCount < $size ),#end
 		#end
 	],

=== modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/jsonTabularInitialize.vm'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/jsonTabularInitialize.vm	2012-12-10 12:54:54 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/jsonTabularInitialize.vm	2013-01-21 06:18:31 +0000
@@ -6,7 +6,8 @@
 		"ous":[
 			#foreach( $orgunit in $currentUser.organisationUnits )
 			   {
-					 "id":  "${orgunit.id}" ,
+					 "id":  "${orgunit.uid}" ,
+					 "localid": "$organisationUnit.id",
 					 "name": "$!encoder.jsonEncode( ${orgunit.name} )",
 					 "leaf": !$orgunit.hasChild()
 			   }#if( $velocityCount < $programs.size() ),#end
@@ -25,7 +26,7 @@
 	"orgunitGroups": [
 		#foreach( $orgunitGroup in $orgunitGroups )
 		  {
-			"id":  "${orgunitGroup.id}" ,
+			"id":  "${orgunitGroup.uid}" ,
 			"name": "$!encoder.jsonEncode( ${orgunitGroup.name} )"
 		  }#if($velocityCount < $orgunitGroups.size()),#end
 		#end

=== modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/jsonminOrganisationUnitChildren.vm'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/jsonminOrganisationUnitChildren.vm	2012-12-10 12:54:54 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/jsonminOrganisationUnitChildren.vm	2013-01-21 06:18:31 +0000
@@ -1,1 +1,1 @@
-#set($size = $units.size())[#foreach($unit in $units){"id":${unit.id},"level":${unit.level},"text":"$encoder.jsonEncode(${unit.name})"#if(!$unit.hasChild()),"leaf":true#end}#if($velocityCount < $size),#end#end]
\ No newline at end of file
+#set($size = $units.size())[#foreach($unit in $units){"id":"${unit.uid}","localid":"${unit.id}","level":${unit.level},"text":"$encoder.jsonEncode(${unit.name})"#if(!$unit.hasChild()),"leaf":true#end}#if($velocityCount < $size),#end#end]
\ No newline at end of file

=== added file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/jsonminOrganisationUnitPaths.vm'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/jsonminOrganisationUnitPaths.vm	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/jsonminOrganisationUnitPaths.vm	2013-01-21 06:18:31 +0000
@@ -0,0 +1,2 @@
+#set( $size = $object.size() )
+{"organisationUnits":[#foreach($unit in $object){"id":"$!{unit.uid}","localid": "$unit.id","name":"$!encoder.jsonEncode(${unit.name})","path":"#foreach($anc in $unit.getAncestors())/${anc.uid}#end"}#if($velocityCount < $size),#end#end]}