← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 10068: Improve Program Statistics.

 

------------------------------------------------------------
revno: 10068
committer: Tran Chau <tran.hispvietnam@xxxxxxxxx>
branch nick: dhis2
timestamp: Fri 2013-03-08 15:47:35 +0700
message:
  Improve Program Statistics.
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceStore.java
  dhis-2/dhis-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/DefaultProgramInstanceService.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/HibernateProgramInstanceStore.java
  dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/hibernate/HibernateProgramStageInstanceStore.java
  dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/report/GenerateStatisticalProgramReportAction.java
  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/webapp/dhis-web-caseentry/javascript/statisticalReport.js
  dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/statisticalProgramReport.vm
  dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/statisticalProgramReportSelect.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/ProgramInstanceService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceService.java	2012-10-06 16:13:56 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceService.java	2013-03-08 08:47:35 +0000
@@ -36,7 +36,6 @@
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.patient.Patient;
 
-
 /**
  * @author Abyot Asalefew
  * @version $Id$
@@ -74,19 +73,30 @@
     Collection<ProgramInstance> getProgramInstances( Patient patient, Program program, boolean completed );
 
     Collection<ProgramInstance> getProgramInstances( Program program, OrganisationUnit organisationUnit );
-    
-    Collection<ProgramInstance> getProgramInstances( Program program, OrganisationUnit organisationUnit, int min, int max );
-    
-    Collection<ProgramInstance> getProgramInstances( Program program, OrganisationUnit organisationUnit, Date startDate, Date endDate );
-
-    Collection<ProgramInstance> getProgramInstances( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate,
-        int min, int max );
+
+    Collection<ProgramInstance> getProgramInstances( Program program, OrganisationUnit organisationUnit, int min,
+        int max );
+
+    Collection<ProgramInstance> getProgramInstances( Program program, OrganisationUnit organisationUnit,
+        Date startDate, Date endDate );
+
+    Collection<ProgramInstance> getProgramInstances( Program program, Collection<Integer> orgunitIds, Date startDate,
+        Date endDate, int min, int max );
 
     int countProgramInstances( Program program, OrganisationUnit organisationUnit );
-    
+
     int countProgramInstances( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate );
-    
+
+    int countProgramInstances( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate,
+        boolean completed );
+
     List<Grid> getProgramInstanceReport( Patient patient, I18n i18n, I18nFormat format );
-    
+
     Grid getProgramInstanceReport( ProgramInstance programInstance, I18n i18n, I18nFormat format );
+    
+    Collection<ProgramInstance> getUnenrollment( Program program, Collection<Integer> orgunitIds, Date startDate,
+        Date endDate );
+
+    int countUnenrollment( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate );
+
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceStore.java	2012-10-06 16:13:56 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstanceStore.java	2013-03-08 08:47:35 +0000
@@ -72,4 +72,11 @@
     int count( Program program, OrganisationUnit organisationUnit );
     
     int count( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate );
+    
+    int count( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate, boolean completed );
+
+    Collection<ProgramInstance> getUnenrollment( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate );
+    
+    int countUnenrollment( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate );
+    
 }

=== 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-03-05 07:29:03 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageInstanceService.java	2013-03-08 08:47:35 +0000
@@ -119,13 +119,18 @@
     // Activity plans
     // -------------------------------------------------------------------------
 
-    List<ProgramStageInstance> activityPlanList( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate,
-        Collection<Integer> statusList, Integer min, Integer max );
+    List<ProgramStageInstance> activityPlanList( Program program, Collection<Integer> orgunitIds, Date startDate,
+        Date endDate, Collection<Integer> statusList, Integer min, Integer max );
 
     Grid activityPlans( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate,
         Collection<Integer> statusList, Integer min, Integer max, I18n i18n );
 
     int getActiveInstanceCount( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate,
         Collection<Integer> statusList );
-    
+
+    Collection<ProgramStageInstance> getProgramStageInstances( Program program, Collection<Integer> orgunitIds,
+        Date startDate, Date endDate, Boolean completed );
+
+    int getOverDueEventCount( ProgramStage programStage, Collection<Integer> orgunitIds, Date startDate, Date endDate );
+
 }

=== 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-03-05 07:29:03 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageInstanceStore.java	2013-03-08 08:47:35 +0000
@@ -84,7 +84,8 @@
 
     Grid getTabularReport( ProgramStage programStage, Map<Integer, OrganisationUnitLevel> orgUnitLevelMap,
         Collection<Integer> orgUnits, List<TabularReportColumn> columns, int level, int maxLevel, Date startDate,
-        Date endDate, boolean descOrder, Boolean completed, Boolean accessPrivateInfo, Integer min, Integer max, I18n i18n );
+        Date endDate, boolean descOrder, Boolean completed, Boolean accessPrivateInfo, Integer min, Integer max,
+        I18n i18n );
 
     int getTabularReportCount( ProgramStage programStage, List<TabularReportColumn> columns,
         Collection<Integer> organisationUnits, int level, int maxLevel, Date startDate, Date endDate, Boolean completed );
@@ -102,8 +103,9 @@
         Collection<Integer> orgunitIds, Date startDate, Date endDate, int status, Integer min, Integer max );
 
     Grid getAggregateReport( int position, ProgramStage programStage, Collection<Integer> orgunitIds,
-        String facilityLB, Integer deGroupBy, Integer deSum, Map<Integer, Collection<String>> deFilters, List<Period> periods,
-        String aggregateType, Integer limit, Boolean useCompletedEvents, I18nFormat format, I18n i18n );
+        String facilityLB, Integer deGroupBy, Integer deSum, Map<Integer, Collection<String>> deFilters,
+        List<Period> periods, String aggregateType, Integer limit, Boolean useCompletedEvents, I18nFormat format,
+        I18n i18n );
 
     // -------------------------------------------------------------------------
     // Activity plans
@@ -111,8 +113,18 @@
 
     List<ProgramStageInstance> getActiveInstance( Program program, Collection<Integer> orgunitIds, Date startDate,
         Date endDate, Collection<Integer> statusList, Integer max, Integer min );
-    
-   int getActiveInstanceCount( Program program, Collection<Integer> orgunitIds, Date startDate,
-        Date endDate, Collection<Integer> statusList );
-   
+
+    int getActiveInstanceCount( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate,
+        Collection<Integer> statusList );
+
+    Collection<ProgramStageInstance> get( Program program, Collection<Integer> orgunitIds, Date startDate,
+        Date endDate, Boolean completed );
+
+    int count( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate, Boolean completed );
+
+    int count( ProgramStage programStage, Collection<Integer> orgunitIds, Date startDate, Date endDate,
+        Boolean completed );
+
+    int getOverDueCount( ProgramStage programStage, Collection<Integer> orgunitIds, Date startDate, Date endDate );
+
 }

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/DefaultProgramInstanceService.java'
--- dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/DefaultProgramInstanceService.java	2013-01-28 06:35:55 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/DefaultProgramInstanceService.java	2013-03-08 08:47:35 +0000
@@ -213,8 +213,8 @@
 
         attrGrid.addRow();
         attrGrid.addValue( i18n.getString( "gender" ) );
-        attrGrid.addValue( i18n.getString( patient.getGender() ));
-        
+        attrGrid.addValue( i18n.getString( patient.getGender() ) );
+
         attrGrid.addRow();
         attrGrid.addValue( i18n.getString( "date_of_birth" ) );
         attrGrid.addValue( format.formatDate( patient.getBirthDate() ) );
@@ -348,6 +348,19 @@
         return grid;
     }
 
+    @Override
+    public Collection<ProgramInstance> getUnenrollment( Program program, Collection<Integer> orgunitIds,
+        Date startDate, Date endDate )
+    {
+        return programInstanceStore.getUnenrollment( program, orgunitIds, startDate, endDate );
+    }
+
+    @Override
+    public int countUnenrollment( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate )
+    {
+        return programInstanceStore.countUnenrollment( program, orgunitIds, startDate, endDate );
+    }
+
     // -------------------------------------------------------------------------
     // due-date && report-date
     // -------------------------------------------------------------------------
@@ -407,4 +420,12 @@
             }
         }
     }
+
+    @Override
+    public int countProgramInstances( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate,
+        boolean completed )
+    {
+        return programInstanceStore.count( program, orgunitIds, startDate, endDate, completed );
+    }
+
 }

=== 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-03-05 07:29:03 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/DefaultProgramStageInstanceService.java	2013-03-08 08:47:35 +0000
@@ -30,6 +30,7 @@
 import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 
@@ -285,57 +286,190 @@
         return programStageInstanceStore.getSendMesssageEvents();
     }
 
+    public Collection<ProgramStageInstance> getProgramStageInstances( Program program, Collection<Integer> orgunitIds,
+        Date startDate, Date endDate, Boolean completed )
+    {
+        return programStageInstanceStore.get( program, orgunitIds, startDate, endDate, completed );
+    }
+
+    public int getProgramStageInstanceCount( Program program, Collection<Integer> orgunitIds, Date startDate,
+        Date endDate, Boolean completed )
+    {
+        return programStageInstanceStore.count( program, orgunitIds, startDate, endDate, completed );
+    }
+
+    public int getProgramStageInstanceCount( ProgramStage programStage, Collection<Integer> orgunitIds, Date startDate,
+        Date endDate, Boolean completed )
+    {
+        return programStageInstanceStore.count( programStage, orgunitIds, startDate, endDate, completed );
+    }
+
     @Override
     public Grid getStatisticalReport( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate,
         I18n i18n, I18nFormat format )
     {
-
         Grid grid = new ListGrid();
-        grid.setTitle( program.getDisplayName() + " ( " + format.formatDate( startDate ) + " - "
-            + format.formatDate( endDate ) + " )" );
+        grid.setTitle( i18n.getString( "program_overview" ) + " - " + program.getDisplayName() );
+        grid.setSubtitle( i18n.getString( "from" ) + " " + format.formatDate( startDate ) + "  "
+            + i18n.getString( "to" ) + " " + format.formatDate( endDate ) );
+
+        grid.addHeader( new GridHeader( "", false, true ) );
+        grid.addHeader( new GridHeader( "", false, false ) );
+        grid.addHeader( new GridHeader( "", false, false ) );
+        grid.addHeader( new GridHeader( "", false, false ) );
+        grid.addHeader( new GridHeader( "", false, false ) );
+        grid.addHeader( new GridHeader( "", false, false ) );
+        grid.addHeader( new GridHeader( "", false, false ) );
+        grid.addHeader( new GridHeader( "", false, false ) );
+
+        // Total new enrollments in the period
 
         int total = programInstanceService.countProgramInstances( program, orgunitIds, startDate, endDate );
-        grid.setSubtitle( i18n.getString( "total_persons_enrolled" ) + ": " + total );
-
-        if ( total > 0 )
-        {
-            grid.addHeader( new GridHeader( i18n.getString( "id" ), true, true ) );
-            grid.addHeader( new GridHeader( i18n.getString( "program_stage" ), false, true ) );
-            grid.addHeader( new GridHeader( i18n.getString( "completed" ), false, false ) );
-            grid.addHeader( new GridHeader( i18n.getString( "percent_completed" ), false, false ) );
-            grid.addHeader( new GridHeader( i18n.getString( "incomplete" ), false, false ) );
-            grid.addHeader( new GridHeader( i18n.getString( "percent_incomplete" ), false, false ) );
-            grid.addHeader( new GridHeader( i18n.getString( "scheduled" ), false, false ) );
-            grid.addHeader( new GridHeader( i18n.getString( "percent_Scheduled" ), false, false ) );
-            grid.addHeader( new GridHeader( i18n.getString( "overdue" ), false, false ) );
-            grid.addHeader( new GridHeader( i18n.getString( "percent_overdue" ), false, false ) );
-
-            for ( ProgramStage programStage : program.getProgramStages() )
-            {
-                grid.addRow();
-                grid.addValue( programStage.getId() );
-                grid.addValue( programStage.getDisplayName() );
-
-                int completed = programStageInstanceStore.getStatisticalProgramStageReport( programStage, orgunitIds,
-                    startDate, endDate, ProgramStageInstance.COMPLETED_STATUS );
-                grid.addValue( completed );
-                grid.addValue( (completed + 0.0) / total );
-
-                int incomplete = programStageInstanceStore.getStatisticalProgramStageReport( programStage, orgunitIds,
-                    startDate, endDate, ProgramStageInstance.VISITED_STATUS );
-                grid.addValue( incomplete );
-                grid.addValue( (incomplete + 0.0) / total );
-
-                int Scheduled = programStageInstanceStore.getStatisticalProgramStageReport( programStage, orgunitIds,
-                    startDate, endDate, ProgramStageInstance.FUTURE_VISIT_STATUS );
-                grid.addValue( Scheduled );
-                grid.addValue( (Scheduled + 0.0) / total );
-
-                int overdue = programStageInstanceStore.getStatisticalProgramStageReport( programStage, orgunitIds,
-                    startDate, endDate, ProgramStageInstance.LATE_VISIT_STATUS );
-                grid.addValue( overdue );
-                grid.addValue( (overdue + 0.0) / total );
-            }
+        grid.addRow();
+        grid.addValue( i18n.getString( "total_new_enrollments_in_this_period" ) );
+        grid.addValue( total );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+
+        // Total programs completed in this period
+
+        int totalCompleted = programInstanceService.countProgramInstances( program, orgunitIds, startDate, endDate,
+            true );
+        grid.addRow();
+        grid.addValue( i18n.getString( "total_programs_completed_in_this_period" ) );
+        grid.addValue( totalCompleted );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+
+        // Total programs discontinued (un-enrollments)
+
+        int totalDiscontinued = programInstanceService.countUnenrollment( program, orgunitIds, startDate, endDate );
+        grid.addRow();
+        grid.addValue( i18n.getString( "total_programs_discontinued_unenrollments" ) );
+        grid.addValue( totalDiscontinued );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+
+        // Average number of stages for complete programs
+
+        int stageCount = program.getProgramStages().size();
+        int stageCompleted = getProgramStageInstanceCount( program, orgunitIds, startDate, endDate, true );
+        double average = 0.0;
+        if ( total != 0 && stageCompleted != 0 )
+        {
+            average = stageCompleted * 100 / (stageCount * total);
+        }
+        grid.addRow();
+        grid.addValue( i18n.getString( "average_number_of_stages_for_complete_programs" ) );
+        grid.addValue( format.formatValue( average ) + "%" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+
+        // Add empty row
+
+        grid.addRow();
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+
+        // Summary by stage
+
+        grid.addRow();
+        grid.addValue( i18n.getString( "summary_by_stage" ) );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+        grid.addValue( "" );
+
+        // Add titles for stage details
+
+        grid.addRow();
+        grid.addValue( i18n.getString( "program_stages" ) );
+        grid.addValue( i18n.getString( "visits_scheduled_all" ) );
+        grid.addValue( i18n.getString( "visits_done" ) );
+        grid.addValue( i18n.getString( "visits_done_percent" ) );
+        grid.addValue( i18n.getString( "forms_completed" ) );
+        grid.addValue( i18n.getString( "forms_completed_percent" ) );
+        grid.addValue( i18n.getString( "visits_overdue" ) );
+        grid.addValue( i18n.getString( "visits_overdue_percent" ) );
+
+        // Add values for stage details
+
+        for ( ProgramStage programStage : program.getProgramStages() )
+        {
+            grid.addRow();
+            grid.addValue( programStage.getDisplayName() );
+
+            // Visits scheduled (All)
+
+            int totalAll = this.getProgramStageInstanceCount( program, orgunitIds, startDate, endDate, null );
+            grid.addValue( total );
+
+            // Visits done (#) = Incomplete + Complete stages.
+
+            int totalCompletedEvent = this.getProgramStageInstanceCount( programStage, orgunitIds, startDate, endDate,
+                true );
+            int totalVisit = this.getProgramStageInstanceCount( programStage, orgunitIds, startDate, endDate, false );
+            grid.addValue( totalCompletedEvent + totalVisit );
+
+            // Visits done (%)
+
+            double percent = 0.0;
+            if ( totalAll != 0 )
+            {
+                percent = (totalCompletedEvent + totalVisit + 0.0) * 100 / totalAll;
+            }
+            grid.addValue( format.formatValue( percent ) + "%" );
+
+            // Forms completed (#) = Program stage instances where the user has
+            // clicked complete.
+
+            grid.addValue( totalCompletedEvent );
+
+            // Forms completed (%)
+            if ( totalAll != 0 )
+            {
+                percent = (totalCompletedEvent + 0.0) * 100 / totalAll;
+            }
+            grid.addValue( format.formatValue( percent ) + "%" );
+
+            // Visits overdue (#)
+
+            int overdue = this.getOverDueEventCount( programStage, orgunitIds, startDate, endDate );
+            grid.addValue( overdue );
+
+            // Visits overdue (%)
+
+            percent = 0.0;
+            if ( totalAll != 0 )
+            {
+                percent = (overdue + 0.0) * 100 / totalAll;
+            }
+            grid.addValue( format.formatValue( percent ) + "%" );
         }
 
         return grid;
@@ -405,7 +539,7 @@
 
             grid.addRow();
             grid.addValue( DateUtils.getMediumDateString( stageInstance.getDueDate() ) );
-            if( stageInstance.getExecutionDate() != null )
+            if ( stageInstance.getExecutionDate() != null )
             {
                 grid.addValue( stageInstance.getOrganisationUnit().getName() );
             }
@@ -427,5 +561,12 @@
     {
         return programStageInstanceStore.getActiveInstanceCount( program, orgunitIds, startDate, endDate, statusList );
     }
-    
+
+    @Override
+    public int getOverDueEventCount( ProgramStage programStage, Collection<Integer> orgunitIds, Date startDate,
+        Date endDate )
+    {
+        return programStageInstanceStore.getOverDueCount( programStage, orgunitIds, startDate, endDate );
+    }
+
 }

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/hibernate/HibernateProgramInstanceStore.java'
--- dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/hibernate/HibernateProgramInstanceStore.java	2012-10-06 16:13:56 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/hibernate/HibernateProgramInstanceStore.java	2013-03-08 08:47:35 +0000
@@ -27,9 +27,10 @@
 
 package org.hisp.dhis.program.hibernate;
 
+import java.util.Collection;
 import java.util.Date;
-import java.util.Collection;
 
+import org.hibernate.Criteria;
 import org.hibernate.criterion.Order;
 import org.hibernate.criterion.Projections;
 import org.hibernate.criterion.Restrictions;
@@ -106,15 +107,16 @@
     @SuppressWarnings( "unchecked" )
     public Collection<ProgramInstance> get( Program program, OrganisationUnit organisationUnit )
     {
-        return getCriteria( Restrictions.eq( "program", program ), Restrictions.isNull( "endDate" ) ).createAlias(
-            "patient", "patient" ).add( Restrictions.eq( "patient.organisationUnit", organisationUnit ) ).list();
+        return getCriteria( Restrictions.eq( "program", program ), Restrictions.isNull( "endDate" ) )
+            .createAlias( "patient", "patient" ).add( Restrictions.eq( "patient.organisationUnit", organisationUnit ) )
+            .list();
     }
 
     @SuppressWarnings( "unchecked" )
     public Collection<ProgramInstance> get( Program program, OrganisationUnit organisationUnit, int min, int max )
     {
-        return getCriteria( Restrictions.eq( "program", program ), Restrictions.isNull( "endDate" ) ).add(
-            Restrictions.eq( "patient.organisationUnit", organisationUnit ) ).createAlias( "patient", "patient" )
+        return getCriteria( Restrictions.eq( "program", program ), Restrictions.isNull( "endDate" ) )
+            .add( Restrictions.eq( "patient.organisationUnit", organisationUnit ) ).createAlias( "patient", "patient" )
             .addOrder( Order.asc( "patient.id" ) ).setFirstResult( min ).setMaxResults( max ).list();
     }
 
@@ -122,10 +124,9 @@
     public Collection<ProgramInstance> get( Program program, OrganisationUnit organisationUnit, Date startDate,
         Date endDate )
     {
-        return getCriteria( Restrictions.eq( "program", program ), Restrictions.isNull( "endDate" ), Restrictions.ge( "enrollmentDate", startDate ),
-            Restrictions.le( "enrollmentDate", endDate ) )
-            .createAlias( "patient", "patient" )
-            .add(Restrictions.eq( "patient.organisationUnit", organisationUnit ) ) 
+        return getCriteria( Restrictions.eq( "program", program ), Restrictions.isNull( "endDate" ),
+            Restrictions.ge( "enrollmentDate", startDate ), Restrictions.le( "enrollmentDate", endDate ) )
+            .createAlias( "patient", "patient" ).add( Restrictions.eq( "patient.organisationUnit", organisationUnit ) )
             .addOrder( Order.asc( "patient.id" ) ).list();
     }
 
@@ -133,20 +134,16 @@
     public Collection<ProgramInstance> get( Program program, Collection<Integer> orgunitIds, Date startDate,
         Date endDate, int min, int max )
     {
-        return getCriteria( Restrictions.eq( "program", program ), 
-            Restrictions.isNull( "endDate" ), 
-            Restrictions.ge( "enrollmentDate", startDate ),
-            Restrictions.le( "enrollmentDate", endDate ) )
-            .createAlias( "patient", "patient" )
-            .createAlias( "patient.organisationUnit", "organisationUnit" )
-            .add(Restrictions.in( "organisationUnit.id", orgunitIds ) )
-            .addOrder( Order.asc( "patient.id" ) ).setFirstResult( min ).setMaxResults( max ).list();
+        return getCriteria( Restrictions.eq( "program", program ), Restrictions.isNull( "endDate" ),
+            Restrictions.ge( "enrollmentDate", startDate ), Restrictions.le( "enrollmentDate", endDate ) )
+            .createAlias( "patient", "patient" ).createAlias( "patient.organisationUnit", "organisationUnit" )
+            .add( Restrictions.in( "organisationUnit.id", orgunitIds ) ).addOrder( Order.asc( "patient.id" ) )
+            .setFirstResult( min ).setMaxResults( max ).list();
     }
 
     public int count( Program program, OrganisationUnit organisationUnit )
     {
-        Number rs = (Number) getCriteria( Restrictions.eq( "program", program ), 
-            Restrictions.isNull( "endDate" ) )
+        Number rs = (Number) getCriteria( Restrictions.eq( "program", program ), Restrictions.isNull( "endDate" ) )
             .createAlias( "patient", "patient" ).add( Restrictions.eq( "patient.organisationUnit", organisationUnit ) )
             .setProjection( Projections.rowCount() ).uniqueResult();
         return rs != null ? rs.intValue() : 0;
@@ -154,14 +151,61 @@
 
     public int count( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate )
     {
-        Number rs = (Number) getCriteria( Restrictions.eq( "program", program ), 
-            Restrictions.isNull( "endDate" ),
+        Number rs = (Number) getCriteria( Restrictions.eq( "program", program ),
             Restrictions.ge( "enrollmentDate", startDate ), 
             Restrictions.le( "enrollmentDate", endDate ) )
             .createAlias( "patient", "patient" )
             .createAlias( "patient.organisationUnit", "organisationUnit" )
-            .add(Restrictions.in( "organisationUnit.id", orgunitIds ) )
-            .setProjection( Projections.rowCount() ).uniqueResult();
+            .add( Restrictions.in( "organisationUnit.id", orgunitIds ) )
+            .setProjection( Projections.rowCount() )
+            .uniqueResult();
+
+        return rs != null ? rs.intValue() : 0;
+    }
+
+    public int count( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate, boolean completed )
+    {
+        Criteria criteria = getCriteria( Restrictions.eq( "program", program ) );
+        criteria.createAlias( "patient", "patient" )
+            .createAlias( "patient.organisationUnit", "organisationUnit" )
+            .add( Restrictions.in( "organisationUnit.id", orgunitIds ) )
+            .add( Restrictions.eq( "completed", completed ) );
+        if ( completed )
+        {
+            criteria.add( Restrictions.between( "endDate", startDate, endDate ) );
+        }
+        else
+        {
+            criteria.add( Restrictions.between( "enrollmentDate", startDate, endDate ) );
+        }
+
+        Number rs = (Number) criteria.setProjection( Projections.rowCount() ).uniqueResult();
+        return rs != null ? rs.intValue() : 0;
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public Collection<ProgramInstance> getUnenrollment( Program program, Collection<Integer> orgunitIds,
+        Date startDate, Date endDate )
+    {
+        return getCriteria( Restrictions.eq( "program", program ), Restrictions.ge( "enrollmentDate", startDate ),
+            Restrictions.le( "enrollmentDate", endDate ) ).createAlias( "patient", "patient" )
+            .createAlias( "programStageInstances", "programStageInstance" )
+            .createAlias( "patient.organisationUnit", "organisationUnit" )
+            .add( Restrictions.in( "organisationUnit.id", orgunitIds ) )
+            .add( Restrictions.eq( "completed", true ) )
+            .add( Restrictions.eq( "programStageInstance.completed", false ) ).list();
+    }
+
+    public int countUnenrollment( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate )
+    {
+        Number rs = (Number) getCriteria( Restrictions.eq( "program", program ),
+            Restrictions.ge( "endDate", startDate ), Restrictions.le( "endDate", endDate ) )
+            .createAlias( "patient", "patient" ).createAlias( "programStageInstances", "programStageInstance" )
+            .createAlias( "patient.organisationUnit", "organisationUnit" )
+            .add( Restrictions.in( "organisationUnit.id", orgunitIds ) ).add( Restrictions.eq( "completed", true ) )
+            .add( Restrictions.eq( "programStageInstance.completed", false ) )
+            .setProjection( Projections.projectionList().add(Projections.countDistinct("id") ) )
+            .uniqueResult();
 
         return rs != null ? rs.intValue() : 0;
     }

=== 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-03-07 05:15:13 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/hibernate/HibernateProgramStageInstanceStore.java	2013-03-08 08:47:35 +0000
@@ -703,10 +703,122 @@
         return list != null ? list.size() : 0;
     }
 
+    public int getOverDueCount( ProgramStage programStage, Collection<Integer> orgunitIds, Date startDate, Date endDate )
+    {
+        Criteria criteria = getCriteria();
+        criteria.createAlias( "programInstance", "programInstance" );
+        criteria.createAlias( "programStage", "programStage" );
+        criteria.createAlias( "programInstance.patient", "patient" );
+        criteria.createAlias( "patient.organisationUnit", "regOrgunit" );
+        criteria.add( Restrictions.eq( "programStage", programStage ) );
+        criteria.add( Restrictions.isNull( "programInstance.endDate" ) );
+        criteria.add( Restrictions.and( Restrictions.isNull( "executionDate" ),
+            Restrictions.between( "dueDate", startDate, new Date() ), Restrictions.in( "regOrgunit.id", orgunitIds ) ) );
+        criteria.setProjection( Projections.rowCount() ).uniqueResult();
+
+        Number rs = (Number) criteria.setProjection( Projections.rowCount() ).uniqueResult();
+
+        return rs != null ? rs.intValue() : 0;
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public Collection<ProgramStageInstance> get( Program program, Collection<Integer> orgunitIds, Date startDate,
+        Date endDate, Boolean completed )
+    {
+        return getCriteria( program, orgunitIds, startDate, endDate, completed ).list();
+    }
+
+    public int count( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate, Boolean completed )
+    {
+        Number rs = (Number) getCriteria( program, orgunitIds, startDate, endDate, completed ).setProjection(
+            Projections.rowCount() ).uniqueResult();
+
+        return rs != null ? rs.intValue() : 0;
+    }
+
+    public int count( ProgramStage programStage, Collection<Integer> orgunitIds, Date startDate, Date endDate,
+        Boolean completed )
+    {
+        Number rs = (Number) getCriteria( programStage, orgunitIds, startDate, endDate, completed ).setProjection(
+            Projections.rowCount() ).uniqueResult();
+
+        return rs != null ? rs.intValue() : 0;
+    }
+
     // -------------------------------------------------------------------------
     // Supportive methods
     // -------------------------------------------------------------------------
 
+    private Criteria getCriteria( Program program, Collection<Integer> orgunitIds, Date startDate, Date endDate,
+        Boolean completed )
+    {
+        Criteria criteria = getCriteria();
+        criteria.createAlias( "programInstance", "programInstance" );
+        criteria.add( Restrictions.eq( "programInstance.program", program ) );
+
+        if ( completed == null )
+        {
+            criteria.add( Restrictions.between( "programInstance.enrollmentDate", startDate, endDate ) );
+        }
+        else
+        {
+            if ( completed )
+            {
+                criteria.add( Restrictions.and( Restrictions.eq( "completed", true ),
+                    Restrictions.between( "executionDate", startDate, endDate ),
+                    Restrictions.in( "organisationUnit.id", orgunitIds ) ) );
+            }
+            else
+            {
+                criteria.createAlias( "programInstance.patient", "patient" );
+                criteria.createAlias( "patient.organisationUnit", "regOrgunit" );
+                criteria.add( Restrictions.or( Restrictions.and( Restrictions.isNull( "executionDate" ),
+                    Restrictions.between( "dueDate", startDate, endDate ),
+                    Restrictions.in( "regOrgunit.id", orgunitIds ) ), Restrictions.and(
+                    Restrictions.eq( "completed", false ), Restrictions.isNotNull( "executionDate" ),
+                    Restrictions.between( "executionDate", startDate, endDate ),
+                    Restrictions.in( "organisationUnit.id", orgunitIds ) ) ) );
+            }
+        }
+
+        return criteria;
+    }
+
+    private Criteria getCriteria( ProgramStage programStage, Collection<Integer> orgunitIds, Date startDate,
+        Date endDate, Boolean completed )
+    {
+        Criteria criteria = getCriteria();
+        criteria.createAlias( "programInstance", "programInstance" );
+        criteria.add( Restrictions.eq( "programStage", programStage ) );
+
+        if ( completed == null )
+        {
+            criteria.add( Restrictions.between( "dueDate", startDate, endDate ) );
+        }
+        else
+        {
+            if ( completed )
+            {
+                criteria.add( Restrictions.and( Restrictions.eq( "completed", true ),
+                    Restrictions.between( "executionDate", startDate, endDate ),
+                    Restrictions.in( "organisationUnit.id", orgunitIds ) ) );
+            }
+            else
+            {
+                criteria.createAlias( "programInstance.patient", "patient" );
+                criteria.createAlias( "patient.organisationUnit", "regOrgunit" );
+                criteria.add( Restrictions.or( Restrictions.and( Restrictions.isNull( "executionDate" ),
+                    Restrictions.between( "dueDate", startDate, endDate ),
+                    Restrictions.in( "regOrgunit.id", orgunitIds ) ), Restrictions.and(
+                    Restrictions.eq( "completed", false ), Restrictions.isNotNull( "executionDate" ),
+                    Restrictions.between( "executionDate", startDate, endDate ),
+                    Restrictions.in( "organisationUnit.id", orgunitIds ) ) ) );
+            }
+        }
+
+        return criteria;
+    }
+
     private String getTabularReportSql( boolean count, ProgramStage programStage, List<TabularReportColumn> columns,
         Collection<Integer> orgUnits, int level, int maxLevel, Date startDate, Date endDate, boolean descOrder,
         Boolean completed, Boolean accessPrivateInfo, Integer min, Integer max )
@@ -971,7 +1083,7 @@
         {
             sql += "LIMIT " + limit;
         }
-        
+
         return sql;
     }
 
@@ -1620,7 +1732,8 @@
                     sql += "( SELECT " + aggregateType + "( cast( value as " + statementBuilder.getDoubleColumnType()
                         + " ))";
                     sql += "    FROM patientdatavalue where dataelementid=pdv_1.dataelementid and "
-                        + "          programstageinstanceid=psi_1.programstageinstanceid and dataelementid=" + deSum + " ";
+                        + "          programstageinstanceid=psi_1.programstageinstanceid and dataelementid=" + deSum
+                        + " ";
                 }
 
                 sql += "FROM programstageinstance psi_1 JOIN patientdatavalue pdv_1 ";

=== modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/report/GenerateStatisticalProgramReportAction.java'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/report/GenerateStatisticalProgramReportAction.java	2013-02-19 07:58:54 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/report/GenerateStatisticalProgramReportAction.java	2013-03-08 08:47:35 +0000
@@ -28,6 +28,7 @@
 package org.hisp.dhis.caseentry.action.report;
 
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.Collection;
 import java.util.Date;
 import java.util.HashSet;
@@ -164,10 +165,9 @@
 
         Program program = programService.getProgram( programId );
 
-        Date sDate = format.parseDate( startDate );
-
-        Date eDate = format.parseDate( endDate );
-
+        Date sDate = format.parseDateTime( startDate );
+        Date eDate = format.parseDateTime( endDate );
+        
         // ---------------------------------------------------------------------
         // Get orgunitIds
         // ---------------------------------------------------------------------

=== 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-03-07 15:11:33 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/resources/org/hisp/dhis/caseentry/i18n_module.properties	2013-03-08 08:47:35 +0000
@@ -478,9 +478,9 @@
 back_to_event_list = Back to event list
 add_and_register_new = Add & Register new
 events_completed = Events completed
-statistical_program = Statistical Program
-statistical_program_report = Statistical program report
-intro_statistical_program = Statistical reports on program performance, e.g. drop-out rates, how many completed every month/year - counts/percentages etc
+statistical_program = Program Statistics
+statistical_program_report = Program statistics
+intro_statistical_program = Program statistics on program performance, e.g. drop-out rates, how many completed every month/year - counts/percentages etc
 percent_completed = Percent Completed
 percent_incomplete = Percent Incomplete
 percent_Scheduled = Percent scheduled
@@ -579,4 +579,18 @@
 view_all = View all
 scheduled_today = Scheduled today
 scheduled_7_days = Scheduled 7 days
-scheduled_30_days = Scheduled 30 days
\ No newline at end of file
+scheduled_30_days = Scheduled 30 days
+program_overview = Program overview
+total_new_enrollments_in_this_period = Total new enrollments in this period
+total_programs_completed_in_this_period	= Total programs completed in this period	
+total_programs_discontinued_unenrollments = Total programs discontinued (un-enrollments)
+average_number_of_stages_for_complete_programs = Average number of stages for complete programs
+summary_by_stage = Summary by stage
+visits_scheduled_all = Visits scheduled (All)
+visits_done = Visits done (#)
+visits_done_percent = Visits done (%)
+forms_completed = Forms completed (#)
+forms_completed_percent = Forms completed (%)
+visits_overdue = Visits overdue (#)
+visits_overdue_percent = Visits overdue (%)
+program_stages = Program stages
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/javascript/statisticalReport.js'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/javascript/statisticalReport.js	2013-02-19 07:58:54 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/javascript/statisticalReport.js	2013-03-08 08:47:35 +0000
@@ -15,13 +15,13 @@
 		jQuery( "#statisticalReportDiv" ).load( "generateStatisticalProgramReport.action",
 		{
 			programId: getFieldValue('programId'),
-			startDate: getFieldValue('startDate'),
-			endDate: getFieldValue( 'endDate' ),
+			startDate: getFieldValue('startDate') + ' 00:00',
+			endDate: getFieldValue( 'endDate' ) + ' 23:59',
 			facilityLB: $('input[name=facilityLB]:checked').val(),
 		}, function() 
 		{ 
-			setTableStyles();
-			hideById('reportForm');
+			hideById('inputCriteria');
+			showById('showDataBtn');
 			showById('statisticalReportDiv');
 			showById('reportTbl');
 			hideLoader();

=== modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/statisticalProgramReport.vm'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/statisticalProgramReport.vm	2012-12-17 08:43:52 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/statisticalProgramReport.vm	2013-03-08 08:47:35 +0000
@@ -1,41 +1,24 @@
-<h6>
-	<a href="javascript:showCriteriaForm();">$i18n.getString("start")</a>
-	&raquo; <a href="javascript:showStatisticalReport();">$!encoder.htmlEncode( $grid.title )</a>
-	<a href="javascript:detailsReport();"><span id="programStageTitleLbl"></span></a>
-	<span id="patientNameLbl"></span>
-</h6>
-<p id="totalLbl" class="hidden"></p>
+<h3>$!encoder.htmlEncode( $grid.title )</h3>
+<h5>$grid.subtitle</h5>
 
-<div id="reportTbl" name="reportTbl">
-	<p id="totalLbl">$!encoder.htmlEncode( $grid.subtitle )</p>
 	<table class="listTable gridTable" width="150px;">
-		<thead>
-			<tr>
-				#foreach( $header in $grid.getVisibleHeaders() )
-					<th #if( !$header.meta )style="text-align:center"#end>$!encoder.htmlEncode( $header.name )</th>
-				#end
-			</tr>
-		</thead>
 		<tbody>
+			#set( $mark = false )
 			#foreach( $row in $grid.getRows() )
-			<tr>
+			#set($rowIdx = $velocityCount)
+			<tr #if($rowIdx > 7) #alternate( $mark ) #end >
+				#if($rowIdx > 7)
+					#set( $mark = !$mark )
+				#end
 				#foreach( $col in $row )
-					#set( $index = ( $velocityCount - 1 ) )
-					#if($index==0)
-						#set( $programStageId = $col )
-					#elseif( $grid.getHeaders().get( $index ).meta )
-						<td>$!encoder.htmlEncode( $col )</td>
+					#if($rowIdx<6) 
+						<td colspan='3'>$col</td>
+					#elseif($rowIdx == 6)
+						<td colspan='3'><h4>$col</h4></td>
+					#elseif($rowIdx == 7)
+						<th>$col</th>
 					#else
-						#if($index==2 || $index==4 || $index==6 || $index==8)
-							#set($status = $index/2)
-							#if($col==0)
-								<td style="text-align:center">$!format.formatValue( $col )</td>
-							#else
-								<td style="text-align:center"><a href="javascript:statisticalProgramDetailsReport($programStageId,$status, $col)">$!format.formatValue( $col )</a></td>
-							#end
-						#else
-							<td style="text-align:center">$!format.formatValue( $col )</td>
-						#end
+						<td >$col</td>
 					#end
 				#end
 			</tr>
@@ -46,4 +29,3 @@
 
 <div id='detailsDiv'></div>
 <div id="viewRecordsDiv"></div>
-

=== modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/statisticalProgramReportSelect.vm'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/statisticalProgramReportSelect.vm	2013-02-19 07:58:54 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/webapp/dhis-web-caseentry/statisticalProgramReportSelect.vm	2013-03-08 08:47:35 +0000
@@ -13,7 +13,8 @@
 	<input type="hidden" id="status" name="status">
 	<input type="hidden" id="type" name="type">
 	<input type="hidden" id="total" name="total">
-	<div class="inputCriteria" style="width:600px;height:180px;margin-bottom:20px;">
+	<input type="button" id='showDataBtn' value="$i18n.getString('data')" onclick="showById('inputCriteria');hideById('showDataBtn')" class="hidden">
+	<div class="inputCriteria" id='inputCriteria' style="width:600px;height:180px;margin-bottom:20px;">
 		<table>	
 			<tr>
 			  <td><label>$i18n.getString( "orgunit_boundary" )</label></td>
@@ -55,7 +56,7 @@
 				<td>
 					<input type="submit" id='generateBtn' name='generateBtn' #if($!programs) #else disabled #end value="$i18n.getString( 'generate' )" onclick='setFieldValue("type","")' style="width:7em" />
 					<input type="submit" id='exportBtn' name='exportBtn' #if($!programs) #else disabled #end value="$i18n.getString( 'export_xls' )" onclick='setFieldValue("type","xls")' style="width:7em" />
-					<input type="button" value="$i18n.getString( 'cancel' )" onclick="hideById('reportForm');" style="width:7em"/>
+					<input type="button" value="$i18n.getString( 'cancel' )" onclick="hideById('inputCriteria');showById('showDataBtn');" style="width:7em"/>
 				</td>
 			</tr>	                		
 		</table>