← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 6763: local vn - Supported in new report as VERTICAL-CATEGORY (wip)

 

------------------------------------------------------------
revno: 6763
committer: Hieu <hieu.hispvietnam@xxxxxxxxx>
branch nick: dhis2
timestamp: Fri 2012-04-27 01:25:07 +0700
message:
  local vn - Supported in new report as VERTICAL-CATEGORY (wip)
added:
  local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionGroupOrder.java
  local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionGroupOrderService.java
  local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionGroupOrderStore.java
  local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportVerticalCategory.java
  local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/hibernate/HibernateCategoryOptionGroupOrderStore.java
  local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/impl/DefaultCategoryOptionGroupOrderService.java
  local/vn/dhis-service-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/hibernate/CategoryOptionGroupOrder.hbm.xml
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/DeleteCategoryOptionGroupOrderAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/GetCategoryOptionGroupOrderAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/GetCategoryOptionsByCategoryAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/SaveCategoryOptionGroupOrderAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/UpdateCategoryOptionGroupOrderAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/UpdateSortedCategoryOptionAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/UpdateSortedCategoryOptionGroupOrderAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/ValidateCategoryOptionGroupOrderAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/category.ajax.js
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/categoryOptionGroupOrder.js
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/grouporder.tooltip.js
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/jsonCategoryOptionGroupOrder.vm
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/jsonCategoryOptions.vm
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/listCategoryOptionGroupOrder.vm
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/report/categoryVerticalExpressionBuilderForm.vm
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/sortCategoryOptions.vm
modified:
  local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReport.java
  local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportCategory.java
  local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportNormal.java
  local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportOrganizationGroupListing.java
  local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportPeriodColumnListing.java
  local/vn/dhis-service-spreadsheet-reporting/src/main/resources/META-INF/dhis/beans.xml
  local/vn/dhis-service-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/hibernate/DataElementGroupOrder.hbm.xml
  local/vn/dhis-service-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/hibernate/ExportReport.hbm.xml
  local/vn/dhis-web-spreadsheet-reporting/src/main/resources/META-INF/dhis/beans.xml
  local/vn/dhis-web-spreadsheet-reporting/src/main/resources/struts.xml
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/attributeValueGroupOrder.js
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/dataElementGroupOrder.js
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/exportItems.js
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/report/addExportItemForm.vm
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/report/updateExportItemForm.vm
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/sortAttributeValues.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
=== added file 'local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionGroupOrder.java'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionGroupOrder.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionGroupOrder.java	2012-04-26 18:25:07 +0000
@@ -0,0 +1,120 @@
+package org.hisp.dhis.reportsheet;
+
+/*
+ * 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.List;
+
+import org.hisp.dhis.dataelement.DataElementCategoryOption;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public class CategoryOptionGroupOrder
+{
+    private int id;
+
+    private String name;
+
+    private List<DataElementCategoryOption> categoryOptions;
+
+    // -------------------------------------------------------------------------
+    // Constructors
+    // -------------------------------------------------------------------------
+
+    public CategoryOptionGroupOrder()
+    {
+    }
+
+    public CategoryOptionGroupOrder( String name )
+    {
+        this.name = name;
+    }
+
+    // -------------------------------------------------------------------------
+    // Getters and setters
+    // -------------------------------------------------------------------------
+
+    public int getId()
+    {
+        return id;
+    }
+
+    public void setId( int id )
+    {
+        this.id = id;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+    public List<DataElementCategoryOption> getCategoryOptions()
+    {
+        return categoryOptions;
+    }
+
+    public void setCategoryOptions( List<DataElementCategoryOption> categoryOptions )
+    {
+        this.categoryOptions = categoryOptions;
+    }
+
+    // -------------------------------------------------------------------------
+    // hashCode and equals
+    // -------------------------------------------------------------------------
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + id;
+        return result;
+    }
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
+            return true;
+        if ( obj == null )
+            return false;
+        if ( getClass() != obj.getClass() )
+            return false;
+        CategoryOptionGroupOrder other = (CategoryOptionGroupOrder) obj;
+        if ( id != other.id )
+            return false;
+        return true;
+    }
+}

=== added file 'local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionGroupOrderService.java'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionGroupOrderService.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionGroupOrderService.java	2012-04-26 18:25:07 +0000
@@ -0,0 +1,50 @@
+package org.hisp.dhis.reportsheet;
+
+/*
+ * 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.
+ */
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public interface CategoryOptionGroupOrderService
+{
+    String ID = CategoryOptionGroupOrderService.class.getName();
+
+    // -------------------------------------------------------------------------
+    // Category Option Group Order
+    // -------------------------------------------------------------------------
+
+    public CategoryOptionGroupOrder getCategoryOptionGroupOrder( Integer id );
+    
+    public CategoryOptionGroupOrder getCategoryOptionGroupOrder( String name, String clazzName, Integer reportId );
+
+    public void updateCategoryOptionGroupOrder( CategoryOptionGroupOrder attributeValueGroupOrder );
+
+    public void deleteCategoryOptionGroupOrder( Integer id );
+
+}
\ No newline at end of file

=== added file 'local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionGroupOrderStore.java'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionGroupOrderStore.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionGroupOrderStore.java	2012-04-26 18:25:07 +0000
@@ -0,0 +1,50 @@
+package org.hisp.dhis.reportsheet;
+
+/*
+ * 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.
+ */
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public interface CategoryOptionGroupOrderStore
+{
+    String ID = CategoryOptionGroupOrderStore.class.getName();
+
+    // -------------------------------------------------------------------------
+    // Category Option Group Order
+    // -------------------------------------------------------------------------
+
+    public CategoryOptionGroupOrder getCategoryOptionGroupOrder( Integer id );
+
+    public CategoryOptionGroupOrder getCategoryOptionGroupOrder( String name, String clazzName, Integer reportId );
+
+    public void updateCategoryOptionGroupOrder( CategoryOptionGroupOrder attributeValueGroupOrder );
+
+    public void deleteCategoryOptionGroupOrder( Integer id );
+
+}

=== modified file 'local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReport.java'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReport.java	2012-04-16 03:00:30 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReport.java	2012-04-26 18:25:07 +0000
@@ -87,25 +87,45 @@
         return results;
     }
 
-    public abstract boolean isAttribute();
+    public boolean isAttribute()
+    {
+        return this.getReportType().equalsIgnoreCase( TYPE.ATTRIBUTE );
+    }
+
+    public boolean isCategory()
+    {
+        return this.getReportType().equalsIgnoreCase( TYPE.CATEGORY );
+    }
+
+    public boolean isCategoryVertical()
+    {
+        return this.getReportType().equalsIgnoreCase( TYPE.CATEGORY_VERTICAL );
+    }
+
+    public boolean isNormal()
+    {
+        return this.getReportType().equalsIgnoreCase( TYPE.NORMAL );
+    }
+
+    public boolean isOrgUnitGroupListing()
+    {
+        return this.getReportType().equalsIgnoreCase( TYPE.ORGANIZATION_GROUP_LISTING );
+    }
+
+    public boolean isPeriodColumnListing()
+    {
+        return this.getReportType().equalsIgnoreCase( TYPE.PERIOD_COLUMN_LISTING );
+    }
+
+    // -------------------------------------------------------------------------
+    // Abstract methods
+    // -------------------------------------------------------------------------
+
+    public abstract String getReportType();
     
-    public abstract boolean isCategory();
-
-    public abstract boolean isOrgUnitGroupListing();
-
-    public abstract boolean isPeriodColumnListing();
-
-    public abstract boolean isNormal();
-
     public abstract List<String> getItemTypes();
 
     // -------------------------------------------------------------------------
-    // Abstract methods
-    // -------------------------------------------------------------------------
-
-    public abstract String getReportType();
-
-    // -------------------------------------------------------------------------
     // Internal classes
     // -------------------------------------------------------------------------
 
@@ -114,7 +134,9 @@
         public static final String NORMAL = "NORMAL";
 
         public static final String CATEGORY = "CATEGORY";
-        
+
+        public static final String CATEGORY_VERTICAL = "CATEGORY_VERTICAL";
+
         public static final String ATTRIBUTE = "ATTRIBUTE";
 
         public static final String PERIOD_COLUMN_LISTING = "PERIOD_COLUMN_LISTING";

=== modified file 'local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportCategory.java'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportCategory.java	2012-04-16 03:00:30 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportCategory.java	2012-04-26 18:25:07 +0000
@@ -68,36 +68,6 @@
     }
 
     @Override
-    public boolean isAttribute()
-    {
-        return false;
-    }
-
-    @Override
-    public boolean isCategory()
-    {
-        return true;
-    }
-
-    @Override
-    public boolean isNormal()
-    {
-        return false;
-    }
-
-    @Override
-    public boolean isOrgUnitGroupListing()
-    {
-        return false;
-    }
-
-    @Override
-    public boolean isPeriodColumnListing()
-    {
-        return false;
-    }
-
-    @Override
     public List<String> getItemTypes()
     {
         List<String> types = new ArrayList<String>();

=== modified file 'local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportNormal.java'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportNormal.java	2012-04-16 03:00:30 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportNormal.java	2012-04-26 18:25:07 +0000
@@ -52,40 +52,11 @@
     }
 
     @Override
-    public boolean isAttribute()
-    {
-        return false;
-    }
-
-    @Override
-    public boolean isCategory()
-    {
-        return false;
-    }
-
-    @Override
-    public boolean isNormal()
-    {
-        return true;
-    }
-
-    @Override
-    public boolean isOrgUnitGroupListing()
-    {
-        return false;
-    }
-
-    @Override
-    public boolean isPeriodColumnListing()
-    {
-        return false;
-    }
-
-    @Override
     public List<String> getItemTypes()
     {
         List<String> types = new ArrayList<String>();
         types.add( ExportItem.TYPE.DATAELEMENT );
+        types.add( ExportItem.TYPE.DATAELEMENT_VALUETYPE_TEXT );
         types.add( ExportItem.TYPE.INDICATOR );
         types.add( ExportItem.TYPE.FORMULA_EXCEL );
 

=== modified file 'local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportOrganizationGroupListing.java'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportOrganizationGroupListing.java	2012-04-16 03:00:30 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportOrganizationGroupListing.java	2012-04-26 18:25:07 +0000
@@ -85,36 +85,6 @@
     }
 
     @Override
-    public boolean isAttribute()
-    {
-        return false;
-    }
-
-    @Override
-    public boolean isCategory()
-    {
-        return false;
-    }
-
-    @Override
-    public boolean isNormal()
-    {
-        return false;
-    }
-
-    @Override
-    public boolean isOrgUnitGroupListing()
-    {
-        return true;
-    }
-
-    @Override
-    public boolean isPeriodColumnListing()
-    {
-        return false;
-    }
-
-    @Override
     public List<String> getItemTypes()
     {
         List<String> types = new ArrayList<String>();

=== modified file 'local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportPeriodColumnListing.java'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportPeriodColumnListing.java	2012-04-16 03:00:30 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportPeriodColumnListing.java	2012-04-26 18:25:07 +0000
@@ -78,36 +78,6 @@
     }
 
     @Override
-    public boolean isAttribute()
-    {
-        return false;
-    }
-
-    @Override
-    public boolean isCategory()
-    {
-        return false;
-    }
-
-    @Override
-    public boolean isNormal()
-    {
-        return false;
-    }
-
-    @Override
-    public boolean isOrgUnitGroupListing()
-    {
-        return false;
-    }
-
-    @Override
-    public boolean isPeriodColumnListing()
-    {
-        return true;
-    }
-
-    @Override
     public List<String> getItemTypes()
     {
         List<String> types = new ArrayList<String>();

=== added file 'local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportVerticalCategory.java'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportVerticalCategory.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/ExportReportVerticalCategory.java	2012-04-26 18:25:07 +0000
@@ -0,0 +1,82 @@
+package org.hisp.dhis.reportsheet;
+
+/*
+ * 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.List;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public class ExportReportVerticalCategory
+    extends ExportReport
+{    
+    private List<CategoryOptionGroupOrder> categoryOptionGroupOrders;
+
+    // -------------------------------------------------------------------------
+    // Constructors
+    // -------------------------------------------------------------------------
+
+    public ExportReportVerticalCategory()
+    {
+        super();
+    }
+
+    // -------------------------------------------------------------------------
+    // Getters and setters
+    // -------------------------------------------------------------------------
+
+    public List<CategoryOptionGroupOrder> getCategoryOptionGroupOrders()
+    {
+        return categoryOptionGroupOrders;
+    }
+
+    public void setCategoryOptionGroupOrders( List<CategoryOptionGroupOrder> categoryOptionGroupOrders )
+    {
+        this.categoryOptionGroupOrders = categoryOptionGroupOrders;
+    }
+
+    @Override
+    public String getReportType()
+    {
+        return ExportReport.TYPE.CATEGORY_VERTICAL;
+    }
+
+    @Override
+    public List<String> getItemTypes()
+    {
+        List<String> types = new ArrayList<String>();
+        types.add( ExportItem.TYPE.DATAELEMENT );
+        types.add( ExportItem.TYPE.DATAELEMENT_CODE );
+        types.add( ExportItem.TYPE.DATAELEMENT_NAME );
+        types.add( ExportItem.TYPE.FORMULA_EXCEL );
+        types.add( ExportItem.TYPE.SERIAL );
+
+        return types;
+    }
+}

=== added file 'local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/hibernate/HibernateCategoryOptionGroupOrderStore.java'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/hibernate/HibernateCategoryOptionGroupOrderStore.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/hibernate/HibernateCategoryOptionGroupOrderStore.java	2012-04-26 18:25:07 +0000
@@ -0,0 +1,102 @@
+package org.hisp.dhis.reportsheet.hibernate;
+
+/*
+ * 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 org.hibernate.SQLQuery;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hisp.dhis.reportsheet.CategoryOptionGroupOrder;
+import org.hisp.dhis.reportsheet.CategoryOptionGroupOrderStore;
+import org.hisp.dhis.reportsheet.ExportReport;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+
+@Transactional
+public class HibernateCategoryOptionGroupOrderStore
+    implements CategoryOptionGroupOrderStore
+{
+    // -------------------------------------------------------------------------
+    // Dependency
+    // -------------------------------------------------------------------------
+
+    private SessionFactory sessionFactory;
+
+    public void setSessionFactory( SessionFactory sessionFactory )
+    {
+        this.sessionFactory = sessionFactory;
+    }
+
+    // -------------------------------------------------------------------------
+    // Data Element Group Order
+    // -------------------------------------------------------------------------
+
+    public CategoryOptionGroupOrder getCategoryOptionGroupOrder( Integer id )
+    {
+        Session session = sessionFactory.getCurrentSession();
+        return (CategoryOptionGroupOrder) session.get( CategoryOptionGroupOrder.class, id );
+    }
+
+    public CategoryOptionGroupOrder getCategoryOptionGroupOrder( String name, String clazzName, Integer reportId )
+    {
+        Session session = sessionFactory.getCurrentSession();
+
+        String sql = "SELECT * FROM reportexcel_categoryoptiongrouporders WHERE lower(name) = :name";
+
+        if ( clazzName.equals( ExportReport.class.getSimpleName() ) )
+        {
+            sql += " AND reportexcelid = :reportId";
+        }
+        else
+        {
+            sql += " AND excelitemgroupid = :reportId";
+        }
+
+        SQLQuery query = session.createSQLQuery( sql );
+
+        query.addEntity( CategoryOptionGroupOrder.class );
+        query.setString( "name", name.toLowerCase() ).setInteger( "reportId", reportId );
+
+        return (CategoryOptionGroupOrder) query.uniqueResult();
+    }
+
+    public void updateCategoryOptionGroupOrder( CategoryOptionGroupOrder categoryOptionGroupOrder )
+    {
+        Session session = sessionFactory.getCurrentSession();
+        session.update( categoryOptionGroupOrder );
+    }
+
+    public void deleteCategoryOptionGroupOrder( Integer id )
+    {
+        Session session = sessionFactory.getCurrentSession();
+        session.delete( this.getCategoryOptionGroupOrder( id ) );
+    }
+}

=== added file 'local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/impl/DefaultCategoryOptionGroupOrderService.java'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/impl/DefaultCategoryOptionGroupOrderService.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/impl/DefaultCategoryOptionGroupOrderService.java	2012-04-26 18:25:07 +0000
@@ -0,0 +1,77 @@
+package org.hisp.dhis.reportsheet.impl;
+
+/*
+ * 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 org.hisp.dhis.reportsheet.CategoryOptionGroupOrder;
+import org.hisp.dhis.reportsheet.CategoryOptionGroupOrderService;
+import org.hisp.dhis.reportsheet.CategoryOptionGroupOrderStore;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+@Transactional
+public class DefaultCategoryOptionGroupOrderService
+    implements CategoryOptionGroupOrderService
+{
+    // -------------------------------------------------------------------------
+    // Dependency
+    // -------------------------------------------------------------------------
+
+    private CategoryOptionGroupOrderStore categoryOptionGroupOrderStore;
+
+    public void setCategoryOptionGroupOrderStore( CategoryOptionGroupOrderStore categoryOptionGroupOrderStore )
+    {
+        this.categoryOptionGroupOrderStore = categoryOptionGroupOrderStore;
+    }
+
+    // -------------------------------------------------------------------------
+    // Data Element Group Order
+    // -------------------------------------------------------------------------
+
+    public CategoryOptionGroupOrder getCategoryOptionGroupOrder( Integer id )
+    {
+        return categoryOptionGroupOrderStore.getCategoryOptionGroupOrder( id );
+    }
+
+    public void updateCategoryOptionGroupOrder( CategoryOptionGroupOrder categoryOptionGroupOrder )
+    {
+        categoryOptionGroupOrderStore.updateCategoryOptionGroupOrder( categoryOptionGroupOrder );
+    }
+
+    public void deleteCategoryOptionGroupOrder( Integer id )
+    {
+        categoryOptionGroupOrderStore.deleteCategoryOptionGroupOrder( id );
+    }
+
+    public CategoryOptionGroupOrder getCategoryOptionGroupOrder( String name, String clazzName, Integer reportId )
+    {
+        return categoryOptionGroupOrderStore.getCategoryOptionGroupOrder( name, clazzName, reportId );
+    }
+}

=== modified file 'local/vn/dhis-service-spreadsheet-reporting/src/main/resources/META-INF/dhis/beans.xml'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/resources/META-INF/dhis/beans.xml	2012-04-16 03:00:30 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/resources/META-INF/dhis/beans.xml	2012-04-26 18:25:07 +0000
@@ -72,6 +72,21 @@
 			ref="org.hisp.dhis.reportsheet.AttributeValueGroupOrderStore" />
 	</bean>
 	
+	<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+	<!-- ATTRIBUTEVALUE-GROUP-ORDER STORE / SERVICE                    -->
+	<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+	
+	<bean id="org.hisp.dhis.reportsheet.CategoryOptionGroupOrderStore"
+		class="org.hisp.dhis.reportsheet.hibernate.HibernateCategoryOptionGroupOrderStore">
+		<property name="sessionFactory" ref="sessionFactory"/>
+	</bean>
+	
+	<bean id="org.hisp.dhis.reportsheet.CategoryOptionGroupOrderService"
+		class="org.hisp.dhis.reportsheet.impl.DefaultCategoryOptionGroupOrderService">
+		<property name="categoryOptionGroupOrderStore"
+			ref="org.hisp.dhis.reportsheet.CategoryOptionGroupOrderStore" />
+	</bean>
+	
 	<!-- Report Location Manager -->
 
 	<bean id="org.hisp.dhis.reportsheet.ReportLocationManager"

=== added file 'local/vn/dhis-service-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/hibernate/CategoryOptionGroupOrder.hbm.xml'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/hibernate/CategoryOptionGroupOrder.hbm.xml	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/hibernate/CategoryOptionGroupOrder.hbm.xml	2012-04-26 18:25:07 +0000
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd";>
+<hibernate-mapping>
+  <class name="org.hisp.dhis.reportsheet.CategoryOptionGroupOrder" table="reportexcel_categoryoptiongrouporders">
+  	    <id name="id" column="id">
+			<generator class="native" />
+		</id>
+
+		<property name="name" column="name" />
+
+		<list name="categoryOptions" table="reportexcel_categoryoptionorders" lazy="false">
+			<key column="id" />
+			<list-index base="0" column="categoryoptionorder" />
+			<many-to-many class="org.hisp.dhis.dataelement.DataElementCategoryOption"
+				column="categoryoptionid" foreign-key="fk_categoryoptionorderid_categoryoptionid" />
+		</list>
+	</class>
+</hibernate-mapping>
\ No newline at end of file

=== modified file 'local/vn/dhis-service-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/hibernate/DataElementGroupOrder.hbm.xml'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/hibernate/DataElementGroupOrder.hbm.xml	2011-07-28 09:50:39 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/hibernate/DataElementGroupOrder.hbm.xml	2012-04-26 18:25:07 +0000
@@ -15,5 +15,5 @@
 			<many-to-many class="org.hisp.dhis.dataelement.DataElement"
 				column="dataelementid" foreign-key="fk_dataelementorderid_dataelementid" />
 		</list>
-  </class>
+	</class>
 </hibernate-mapping>
\ No newline at end of file

=== modified file 'local/vn/dhis-service-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/hibernate/ExportReport.hbm.xml'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/hibernate/ExportReport.hbm.xml	2012-04-25 09:59:24 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/hibernate/ExportReport.hbm.xml	2012-04-26 18:25:07 +0000
@@ -31,38 +31,53 @@
 			<key column="reportexcelid" />
 			<many-to-many class="org.hisp.dhis.user.UserAuthorityGroup"
 				column="userroleid"  foreign-key="fk_reportexcel_userroles"/>
-		</set>		
+		</set>
 		
+		<!-- NORMAL -->
 		<joined-subclass name="org.hisp.dhis.reportsheet.ExportReportNormal" table="reportexcels_normal">
-			<key column="reportexcelid" />			
+			<key column="reportexcelid" />
 		</joined-subclass>
 		
+		<!-- PERIOD-LISTING -->
 		<joined-subclass name="org.hisp.dhis.reportsheet.ExportReportPeriodColumnListing" table="reportexcels_periodcolumnlisting">
-			<key column="reportexcelid" />		
+			<key column="reportexcelid" />
 			<set name="periodColumns" table="reportexcel_periodcolumns" cascade="all" lazy="false">
 				<key column="reportexcelid"/>
 				<one-to-many class="org.hisp.dhis.reportsheet.PeriodColumn"/>
-			</set>	
+			</set>
 		</joined-subclass>
 		
+		<!-- CATEGORY -->
 		<joined-subclass name="org.hisp.dhis.reportsheet.ExportReportCategory" table="reportexcels_category">
 			<key column="reportexcelid"/>
 			<list name="dataElementOrders" table="reportexcel_dataelementgrouporders" cascade="all" lazy="false">
 				<key column="reportexcelid"/>
 				<list-index base="0" column="dataelementgrouporder"/>
 				<one-to-many class="org.hisp.dhis.reportsheet.DataElementGroupOrder"/>
-		    </list>				
-		</joined-subclass>
-		
+		    </list>
+		</joined-subclass>
+		
+		<!-- CATEGORY-VERTICAL -->
+		<joined-subclass name="org.hisp.dhis.reportsheet.ExportReportVerticalCategory" table="reportexcels_verticalcategory">
+			<key column="reportexcelid"/>
+			<list name="categoryOptionGroupOrders" table="reportexcel_categoryoptiongrouporders" cascade="all" lazy="false">
+				<key column="reportexcelid"/>
+				<list-index base="0" column="categoryoptiongrouporder"/>
+				<one-to-many class="org.hisp.dhis.reportsheet.CategoryOptionGroupOrder"/>
+		    </list>
+		</joined-subclass>
+		
+		<!-- ATTRIBUTE -->
 		<joined-subclass name="org.hisp.dhis.reportsheet.ExportReportAttribute" table="reportexcels_attribute">
 			<key column="reportexcelid"/>
 			<list name="attributeValueOrders" table="reportexcel_attributevaluegrouporders" cascade="all" lazy="false">
 				<key column="reportexcelid"/>
 				<list-index base="0" column="attributevaluegrouporder"/>
 				<one-to-many class="org.hisp.dhis.reportsheet.AttributeValueGroupOrder"/>
-		    </list>				
+		    </list>
 		</joined-subclass>
 		
+		<!-- ORG-UNIT-LISTING -->
 		<joined-subclass name="org.hisp.dhis.reportsheet.ExportReportOrganizationGroupListing" table="reportexcels_organizationgrouplisting">			
 			<key column="reportexcelid"/>			
 			<list name="organisationUnitGroups" table="reportexcel_organisationgroup">

=== added directory 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup'
=== added directory 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action'
=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/DeleteCategoryOptionGroupOrderAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/DeleteCategoryOptionGroupOrderAction.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/DeleteCategoryOptionGroupOrderAction.java	2012-04-26 18:25:07 +0000
@@ -0,0 +1,71 @@
+package org.hisp.dhis.reportsheet.cogroup.action;
+
+/*
+ * 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 org.hisp.dhis.reportsheet.CategoryOptionGroupOrderService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.opensymphony.xwork2.Action;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public class DeleteCategoryOptionGroupOrderAction
+    implements Action
+{
+    // -------------------------------------------------------------------------
+    // Dependency
+    // -------------------------------------------------------------------------
+
+    @Autowired
+    private CategoryOptionGroupOrderService categoryOptionGroupOrderService;
+
+    // -------------------------------------------------------------------------
+    // Input & Output
+    // -------------------------------------------------------------------------
+
+    private Integer id;
+
+    public void setId( Integer id )
+    {
+        this.id = id;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    public String execute()
+        throws Exception
+    {
+        categoryOptionGroupOrderService.deleteCategoryOptionGroupOrder( id );
+
+        return SUCCESS;
+    }
+}

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/GetCategoryOptionGroupOrderAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/GetCategoryOptionGroupOrderAction.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/GetCategoryOptionGroupOrderAction.java	2012-04-26 18:25:07 +0000
@@ -0,0 +1,104 @@
+package org.hisp.dhis.reportsheet.cogroup.action;
+
+/*
+ * 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 org.hisp.dhis.reportsheet.CategoryOptionGroupOrder;
+import org.hisp.dhis.reportsheet.CategoryOptionGroupOrderService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.opensymphony.xwork2.Action;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public class GetCategoryOptionGroupOrderAction
+    implements Action
+{
+    // -------------------------------------------------------------------------
+    // Dependency
+    // -------------------------------------------------------------------------
+
+    @Autowired
+    private CategoryOptionGroupOrderService categoryOptionGroupOrderService;
+
+    // -------------------------------------------------------------------------
+    // Input & Output
+    // -------------------------------------------------------------------------
+
+    private Integer id;
+
+    public void setId( Integer id )
+    {
+        this.id = id;
+    }
+
+    private Integer reportId;
+
+    public Integer getReportId()
+    {
+        return reportId;
+    }
+
+    public void setReportId( Integer reportId )
+    {
+        this.reportId = reportId;
+    }
+
+    private String clazzName;
+
+    public void setClazzName( String clazzName )
+    {
+        this.clazzName = clazzName;
+    }
+
+    public String getClazzName()
+    {
+        return clazzName;
+    }
+
+    private CategoryOptionGroupOrder categoryOptionGroupOrder;
+
+    public CategoryOptionGroupOrder getCategoryOptionGroupOrder()
+    {
+        return categoryOptionGroupOrder;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    public String execute()
+        throws Exception
+    {
+        categoryOptionGroupOrder = categoryOptionGroupOrderService.getCategoryOptionGroupOrder( id );
+
+        return SUCCESS;
+    }
+
+}

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/GetCategoryOptionsByCategoryAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/GetCategoryOptionsByCategoryAction.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/GetCategoryOptionsByCategoryAction.java	2012-04-26 18:25:07 +0000
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+package org.hisp.dhis.reportsheet.cogroup.action;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.hisp.dhis.dataelement.DataElementCategory;
+import org.hisp.dhis.dataelement.DataElementCategoryOption;
+import org.hisp.dhis.dataelement.DataElementCategoryService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.opensymphony.xwork2.Action;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public class GetCategoryOptionsByCategoryAction
+    implements Action
+{
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    @Autowired
+    private DataElementCategoryService categoryService;
+
+    // -------------------------------------------------------------------------
+    // Input && Output
+    // -------------------------------------------------------------------------
+
+    private Integer categoryId;
+
+    public void setAttributeId( Integer categoryId )
+    {
+        this.categoryId = categoryId;
+    }
+
+    private Collection<DataElementCategoryOption> categoryOptions = new ArrayList<DataElementCategoryOption>();
+
+    public Collection<DataElementCategoryOption> getCategoryOptions()
+    {
+        return categoryOptions;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    @Override
+    public String execute()
+        throws Exception
+    {
+        DataElementCategory category = categoryService.getDataElementCategory( categoryId );
+
+        if ( category != null )
+        {
+            categoryOptions = category.getCategoryOptions();
+        }
+
+        return SUCCESS;
+    }
+}

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/SaveCategoryOptionGroupOrderAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/SaveCategoryOptionGroupOrderAction.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/SaveCategoryOptionGroupOrderAction.java	2012-04-26 18:25:07 +0000
@@ -0,0 +1,156 @@
+package org.hisp.dhis.reportsheet.cogroup.action;
+
+/*
+ * 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.List;
+
+import org.hisp.dhis.dataelement.DataElementCategoryOption;
+import org.hisp.dhis.dataelement.DataElementCategoryService;
+import org.hisp.dhis.reportsheet.CategoryOptionGroupOrder;
+import org.hisp.dhis.reportsheet.ExportReport;
+import org.hisp.dhis.reportsheet.ExportReportService;
+import org.hisp.dhis.reportsheet.ExportReportVerticalCategory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.opensymphony.xwork2.Action;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+
+public class SaveCategoryOptionGroupOrderAction
+    implements Action
+{
+    // -------------------------------------------------------------------------
+    // Dependency
+    // -------------------------------------------------------------------------
+
+    @Autowired
+    private DataElementCategoryService categoryService;
+
+    @Autowired
+    private ExportReportService exportReportService;
+
+    // -------------------------------------------------------------------------
+    // Input
+    // -------------------------------------------------------------------------
+
+    private Integer id;
+
+    private String name;
+
+    private String clazzName;
+
+    private List<String> categoryOptionIds = new ArrayList<String>();
+
+    // -------------------------------------------------------------------------
+    // Getter & Setter
+    // -------------------------------------------------------------------------
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+    public void setId( Integer id )
+    {
+        this.id = id;
+    }
+
+    public Integer getId()
+    {
+        return id;
+    }
+
+    public void setClazzName( String clazzName )
+    {
+        this.clazzName = clazzName;
+    }
+
+    public void setCategoryOptionIds( List<String> categoryOptionIds )
+    {
+        this.categoryOptionIds = categoryOptionIds;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    @SuppressWarnings( "unchecked" )
+    public String execute()
+        throws Exception
+    {
+        CategoryOptionGroupOrder categoryOptionGroupOrder = new CategoryOptionGroupOrder( name );
+
+        List<String> finalList = new ArrayList<String>();
+        List<DataElementCategoryOption> categoryOptions = new ArrayList<DataElementCategoryOption>();
+
+        removeDuplicatedItems( categoryOptionIds, finalList );
+
+        for ( String id : this.categoryOptionIds )
+        {
+            DataElementCategoryOption categoryOption = categoryService.getDataElementCategoryOption( Integer
+                .parseInt( id ) );
+            categoryOptions.add( categoryOption );
+        }
+
+        categoryOptionGroupOrder.setCategoryOptions( categoryOptions );
+
+        if ( clazzName.equals( ExportReport.class.getSimpleName() ) )
+        {
+            ExportReportVerticalCategory exportReportVerticalCategory = (ExportReportVerticalCategory) exportReportService
+                .getExportReport( id );
+
+            List<CategoryOptionGroupOrder> categoryOptionGroupOrders = exportReportVerticalCategory
+                .getCategoryOptionGroupOrders();
+
+            categoryOptionGroupOrders.add( categoryOptionGroupOrder );
+
+            exportReportVerticalCategory.setCategoryOptionGroupOrders( categoryOptionGroupOrders );
+
+            exportReportService.updateExportReport( exportReportVerticalCategory );
+        }
+
+        categoryOptions = null;
+
+        return SUCCESS;
+    }
+
+    private static void removeDuplicatedItems( List<String> a, List<String> b )
+    {
+        for ( String s1 : a )
+        {
+            if ( !b.contains( s1 ) )
+            {
+                b.add( s1 );
+            }
+        }
+    }
+}

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/UpdateCategoryOptionGroupOrderAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/UpdateCategoryOptionGroupOrderAction.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/UpdateCategoryOptionGroupOrderAction.java	2012-04-26 18:25:07 +0000
@@ -0,0 +1,140 @@
+package org.hisp.dhis.reportsheet.cogroup.action;
+
+/*
+ * 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.List;
+
+import org.hisp.dhis.dataelement.DataElementCategoryOption;
+import org.hisp.dhis.dataelement.DataElementCategoryService;
+import org.hisp.dhis.reportsheet.CategoryOptionGroupOrder;
+import org.hisp.dhis.reportsheet.CategoryOptionGroupOrderService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.opensymphony.xwork2.Action;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public class UpdateCategoryOptionGroupOrderAction
+    implements Action
+{
+    // -------------------------------------------------------------------------
+    // Dependency
+    // -------------------------------------------------------------------------
+
+    @Autowired
+    private DataElementCategoryService categoryService;
+
+    @Autowired
+    private CategoryOptionGroupOrderService categoryOptionGroupOrderService;
+
+    // -------------------------------------------------------------------------
+    // Input
+    // -------------------------------------------------------------------------
+
+    private Integer id;
+
+    private Integer categoryOptionGroupOrderId;
+
+    private String name;
+
+    private List<String> categoryOptionIds = new ArrayList<String>();
+
+    // -------------------------------------------------------------------------
+    // Getter & Setter
+    // -------------------------------------------------------------------------
+
+    public void setCategoryOptionGroupOrderId( Integer categoryOptionGroupOrderId )
+    {
+        this.categoryOptionGroupOrderId = categoryOptionGroupOrderId;
+    }
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+    public Integer getId()
+    {
+        return id;
+    }
+
+    public void setId( Integer id )
+    {
+        this.id = id;
+    }
+
+    public void setCategoryOptionIds( List<String> categoryOptionIds )
+    {
+        this.categoryOptionIds = categoryOptionIds;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    public String execute()
+        throws Exception
+    {
+        CategoryOptionGroupOrder categoryOptionGroupOrder = categoryOptionGroupOrderService
+            .getCategoryOptionGroupOrder( categoryOptionGroupOrderId );
+
+        categoryOptionGroupOrder.setName( name );
+
+        List<String> finalList = new ArrayList<String>();
+        List<DataElementCategoryOption> categoryOptions = new ArrayList<DataElementCategoryOption>();
+
+        removeDuplicatedItems( categoryOptionIds, finalList );
+
+        for ( String id : this.categoryOptionIds )
+        {
+            DataElementCategoryOption categoryOption = categoryService.getDataElementCategoryOption( Integer
+                .parseInt( id ) );
+            categoryOptions.add( categoryOption );
+        }
+
+        categoryOptionGroupOrder.setCategoryOptions( categoryOptions );
+
+        categoryOptionGroupOrderService.updateCategoryOptionGroupOrder( categoryOptionGroupOrder );
+
+        return SUCCESS;
+    }
+
+    private static void removeDuplicatedItems( List<String> a, List<String> b )
+    {
+        for ( String s1 : a )
+        {
+            if ( !b.contains( s1 ) )
+            {
+                b.add( s1 );
+            }
+        }
+    }
+}

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/UpdateSortedCategoryOptionAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/UpdateSortedCategoryOptionAction.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/UpdateSortedCategoryOptionAction.java	2012-04-26 18:25:07 +0000
@@ -0,0 +1,142 @@
+package org.hisp.dhis.reportsheet.cogroup.action;
+
+/*
+ * 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.List;
+
+import org.hisp.dhis.dataelement.DataElementCategoryOption;
+import org.hisp.dhis.dataelement.DataElementCategoryService;
+import org.hisp.dhis.i18n.I18n;
+import org.hisp.dhis.reportsheet.CategoryOptionGroupOrder;
+import org.hisp.dhis.reportsheet.CategoryOptionGroupOrderService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.opensymphony.xwork2.Action;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public class UpdateSortedCategoryOptionAction
+    implements Action
+{
+    // -------------------------------------------------------------------------
+    // Dependency
+    // -------------------------------------------------------------------------
+
+    @Autowired
+    private DataElementCategoryService categoryService;
+
+    // -------------------------------------------------------------------------
+    // I18n
+    // -------------------------------------------------------------------------
+    
+    @Autowired
+    private CategoryOptionGroupOrderService categoryOptionGroupOrderService;
+
+    public void setI18n( I18n i18n )
+    {
+        this.i18n = i18n;
+    }
+
+    // -------------------------------------------------------------------------
+    // Input & Output
+    // -------------------------------------------------------------------------
+
+    private Integer id;
+
+    private Integer reportId;
+
+    private List<Integer> categoryOptionIds = new ArrayList<Integer>();
+
+    public String message;
+
+    public I18n i18n;
+
+    // -------------------------------------------------------------------------
+    // Getter & Setter
+    // -------------------------------------------------------------------------
+
+    public String getMessage()
+    {
+        return message;
+    }
+
+    public void setReportId( Integer reportId )
+    {
+        this.reportId = reportId;
+    }
+
+    public Integer getReportId()
+    {
+        return reportId;
+    }
+
+    public void setId( Integer id )
+    {
+        this.id = id;
+    }
+
+    public Integer getId()
+    {
+        return id;
+    }
+
+    public void setCategoryOptionIds( List<Integer> categoryOptionIds )
+    {
+        this.categoryOptionIds = categoryOptionIds;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    public String execute()
+        throws Exception
+    {
+        CategoryOptionGroupOrder categoryOptionGroupOrder = categoryOptionGroupOrderService
+            .getCategoryOptionGroupOrder( id );
+
+        List<DataElementCategoryOption> categoryOptions = new ArrayList<DataElementCategoryOption>();
+
+        for ( Integer id : this.categoryOptionIds )
+        {
+            DataElementCategoryOption categoryOption = categoryService.getDataElementCategoryOption( id );
+            categoryOptions.add( categoryOption );
+        }
+
+        categoryOptionGroupOrder.setCategoryOptions( categoryOptions );
+
+        message = i18n.getString( "update_sort_categoryoption_success" );
+
+        categoryOptionGroupOrderService.updateCategoryOptionGroupOrder( categoryOptionGroupOrder );
+
+        return SUCCESS;
+    }
+}

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/UpdateSortedCategoryOptionGroupOrderAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/UpdateSortedCategoryOptionGroupOrderAction.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/UpdateSortedCategoryOptionGroupOrderAction.java	2012-04-26 18:25:07 +0000
@@ -0,0 +1,120 @@
+package org.hisp.dhis.reportsheet.cogroup.action;
+
+/*
+ * Copyright (c) 2004-2011, 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.List;
+
+import org.hisp.dhis.reportsheet.CategoryOptionGroupOrder;
+import org.hisp.dhis.reportsheet.CategoryOptionGroupOrderService;
+import org.hisp.dhis.reportsheet.ExportReport;
+import org.hisp.dhis.reportsheet.ExportReportService;
+import org.hisp.dhis.reportsheet.ExportReportVerticalCategory;
+import org.hisp.dhis.reportsheet.action.ActionSupport;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public class UpdateSortedCategoryOptionGroupOrderAction
+    extends ActionSupport
+{
+    // -------------------------------------------------------------------------
+    // Dependency
+    // -------------------------------------------------------------------------
+
+    @Autowired
+    private CategoryOptionGroupOrderService categoryOptionGroupOrderService;
+
+    @Autowired
+    private ExportReportService exportReportService;
+
+    // -------------------------------------------------------------------------
+    // Input & Output
+    // -------------------------------------------------------------------------
+
+    private Integer reportId;
+
+    public Integer getReportId()
+    {
+        return reportId;
+    }
+
+    public void setReportId( Integer reportId )
+    {
+        this.reportId = reportId;
+    }
+
+    private String clazzName;
+
+    public void setClazzName( String clazzName )
+    {
+        this.clazzName = clazzName;
+    }
+
+    private List<String> categoryOptionGroupOrderId = new ArrayList<String>();
+
+    public void setCategoryOptionGroupOrderId( List<String> categoryOptionGroupOrderId )
+    {
+        this.categoryOptionGroupOrderId = categoryOptionGroupOrderId;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    public String execute()
+        throws Exception
+    {
+        List<CategoryOptionGroupOrder> categoryOptionGroupOrders = new ArrayList<CategoryOptionGroupOrder>();
+
+        for ( String id : this.categoryOptionGroupOrderId )
+        {
+            CategoryOptionGroupOrder coGroupOrder = categoryOptionGroupOrderService
+                .getCategoryOptionGroupOrder( Integer.parseInt( id ) );
+
+            categoryOptionGroupOrders.add( coGroupOrder );
+        }
+
+        if ( clazzName.equals( ExportReport.class.getSimpleName() ) )
+        {
+            ExportReportVerticalCategory exportReportVerticalCategory = (ExportReportVerticalCategory) exportReportService
+                .getExportReport( reportId );
+
+            exportReportVerticalCategory.setCategoryOptionGroupOrders( categoryOptionGroupOrders );
+
+            exportReportService.updateExportReport( exportReportVerticalCategory );
+        }
+
+        message = i18n.getString( "update_successful" );
+
+        return SUCCESS;
+    }
+
+}

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/ValidateCategoryOptionGroupOrderAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/ValidateCategoryOptionGroupOrderAction.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/ValidateCategoryOptionGroupOrderAction.java	2012-04-26 18:25:07 +0000
@@ -0,0 +1,100 @@
+package org.hisp.dhis.reportsheet.cogroup.action;
+
+/*
+ * Copyright (c) 2004-2011, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software without
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import org.hisp.dhis.reportsheet.CategoryOptionGroupOrder;
+import org.hisp.dhis.reportsheet.CategoryOptionGroupOrderService;
+import org.hisp.dhis.reportsheet.action.ActionSupport;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public class ValidateCategoryOptionGroupOrderAction
+    extends ActionSupport
+{
+    // -------------------------------------------------------------------------
+    // Dependency
+    // -------------------------------------------------------------------------
+
+    @Autowired
+    private CategoryOptionGroupOrderService categoryOptionGroupOrderService;
+
+    // -------------------------------------------------------------------------
+    // Input & Output
+    // -------------------------------------------------------------------------
+
+    private Integer id;
+
+    public void setId( Integer id )
+    {
+        this.id = id;
+    }
+
+    private Integer reportId;
+
+    public void setReportId( Integer reportId )
+    {
+        this.reportId = reportId;
+    }
+
+    private String clazzName;
+
+    public void setClazzName( String clazzName )
+    {
+        this.clazzName = clazzName;
+    }
+
+    private String name;
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+    // -------------------------------------------------------------------------
+    // Input & Output
+    // -------------------------------------------------------------------------
+
+    public String execute()
+        throws Exception
+    {
+        CategoryOptionGroupOrder match = categoryOptionGroupOrderService.getCategoryOptionGroupOrder( name, clazzName,
+            reportId );
+
+        if ( match != null && (id == null || match.getId() != id) )
+        {
+            message = i18n.getString( "name_ready_exist" );
+
+            return ERROR;
+        }
+
+        return SUCCESS;
+    }
+}

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/resources/META-INF/dhis/beans.xml'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/resources/META-INF/dhis/beans.xml	2012-04-19 03:58:49 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/resources/META-INF/dhis/beans.xml	2012-04-26 18:25:07 +0000
@@ -258,6 +258,48 @@
 		<property name="dataElementService" ref="org.hisp.dhis.dataelement.DataElementService" />
 		<property name="dataElementGroupOrderService" ref="org.hisp.dhis.reportsheet.DataElementGroupOrderService" />
 	</bean>
+	
+	<!-- REPORT EXCEL CATEGORY-VERTICAL BEAN -->
+
+	<bean
+		id="org.hisp.dhis.reportsheet.cogroup.action.ValidateCategoryOptionGroupOrderAction"
+		class="org.hisp.dhis.reportsheet.cogroup.action.ValidateCategoryOptionGroupOrderAction"
+		scope="prototype" />
+	
+	<bean
+		id="org.hisp.dhis.reportsheet.cogroup.action.SaveCategoryOptionGroupOrderAction"
+		class="org.hisp.dhis.reportsheet.cogroup.action.SaveCategoryOptionGroupOrderAction"
+		scope="prototype" />
+
+	<bean
+		id="org.hisp.dhis.reportsheet.cogroup.action.UpdateCategoryOptionGroupOrderAction"
+		class="org.hisp.dhis.reportsheet.cogroup.action.UpdateCategoryOptionGroupOrderAction"
+		scope="prototype" />
+
+	<bean
+		id="org.hisp.dhis.reportsheet.cogroup.action.DeleteCategoryOptionGroupOrderAction"
+		class="org.hisp.dhis.reportsheet.cogroup.action.DeleteCategoryOptionGroupOrderAction"
+		scope="prototype" />
+
+	<bean
+		id="org.hisp.dhis.reportsheet.cogroup.action.GetCategoryOptionGroupOrderAction"
+		class="org.hisp.dhis.reportsheet.cogroup.action.GetCategoryOptionGroupOrderAction"
+		scope="prototype" />
+
+	<bean
+		id="org.hisp.dhis.reportsheet.cogroup.action.UpdateSortedCategoryOptionGroupOrderAction"
+		class="org.hisp.dhis.reportsheet.cogroup.action.UpdateSortedCategoryOptionGroupOrderAction"
+		scope="prototype" />
+	
+	<bean
+		id="org.hisp.dhis.reportsheet.cogroup.action.UpdateSortedCategoryOptionAction"
+		class="org.hisp.dhis.reportsheet.cogroup.action.UpdateSortedCategoryOptionAction"
+		scope="prototype" />
+	
+	<bean
+		id="org.hisp.dhis.reportsheet.cogroup.action.GetCategoryOptionsByCategoryAction"
+		class="org.hisp.dhis.reportsheet.cogroup.action.GetCategoryOptionsByCategoryAction"
+		scope="prototype" />
 
 	<!-- REPORT EXCEL ATTRIBUTE BEAN -->
 

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/resources/struts.xml'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/resources/struts.xml	2012-04-19 03:58:49 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/resources/struts.xml	2012-04-26 18:25:07 +0000
@@ -188,6 +188,108 @@
 				/dhis-web-commons/ajax/jsonResponseError.vm</result>
 			<param name="onExceptionReturn">plainTextError</param>
 		</action>
+		
+		<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+		<!-- CATEGORYOPTION GROUP ORDER FOR CATEGORY OPTION 			   -->
+		<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+		<action name="listCategoryOptionGroupOrderForExportReport"
+			class="org.hisp.dhis.reportsheet.exportreport.action.GetExportReportAction">
+			<result name="success" type="velocity">/main.vm</result>
+			<param name="page">/dhis-web-spreadsheet-reporting/listCategoryOptionGroupOrder.vm</param>
+			<param name="menu">/dhis-web-spreadsheet-reporting/menu.vm</param>
+			<param name="javascripts">javascript/category.ajax.js,javascript/categoryOptionGroupOrder.js</param>
+			<param name="stylesheets">style/basic.css,style/style.css</param>
+		</action>
+		
+		<action name="listCategoryOptionGroupOrderForImportReport"
+			class="org.hisp.dhis.reportsheet.importreport.action.GetImportReportAction">
+			<result name="success" type="velocity">/main.vm</result>
+			<param name="page">/dhis-web-spreadsheet-reporting/listCategoryOptionGroupOrder.vm</param>
+			<param name="menu">/dhis-web-spreadsheet-reporting/menu.vm</param>
+			<param name="javascripts">javascript/category.ajax.js,javascript/categoryOptionGroupOrder.js</param>
+			<param name="stylesheets">style/basic.css,style/style.css</param>
+		</action>	
+		
+		<action name="validateCategoryOptionGroupOrder"
+			class="org.hisp.dhis.reportsheet.cogroup.action.ValidateCategoryOptionGroupOrderAction">
+			<result name="success" type="velocity-json">
+				/dhis-web-commons/ajax/jsonResponseSuccess.vm</result>
+			<result name="error" type="velocity-json">
+				/dhis-web-commons/ajax/jsonResponseError.vm</result>
+		</action>
+		
+		<action name="addCategoryOptionGroupOrderForExportReport"
+			class="org.hisp.dhis.reportsheet.cogroup.action.SaveCategoryOptionGroupOrderAction">
+			<result name="success" type="redirect">
+				listCategoryOptionGroupOrderForExportReport.action?id=${id}</result>
+		</action>
+		
+		<action name="addCategoryOptionGroupOrderForImportReport"
+			class="org.hisp.dhis.reportsheet.cogroup.action.SaveCategoryOptionGroupOrderAction">
+			<result name="success" type="redirect">
+				listCategoryOptionGroupOrderForImportReport.action?id=${id}
+			</result>
+		</action>
+
+		<action name="updateCategoryOptionGroupOrderForExportReport"
+			class="org.hisp.dhis.reportsheet.cogroup.action.UpdateCategoryOptionGroupOrderAction">
+			<result name="success" type="redirect">
+				listCategoryOptionGroupOrderForExportReport.action?id=${id}</result>
+		</action>
+		
+		<action name="updateCategoryOptionGroupOrderForImportReport"
+			class="org.hisp.dhis.reportsheet.cogroup.action.UpdateCategoryOptionGroupOrderAction">
+			<result name="success" type="redirect">
+				listCategoryOptionGroupOrderForImportReport.action?id=${id}
+			</result>
+		</action>
+		
+		<action name="deleteCategoryOptionGroupOrder"
+			class="org.hisp.dhis.reportsheet.cogroup.action.DeleteCategoryOptionGroupOrderAction">
+			<result name="success" type="velocity-json">
+				/dhis-web-commons/ajax/jsonResponseSuccess.vm</result>
+		</action>
+		
+		<action name="updateSortCategoryOptionGroupOrder"
+			class="org.hisp.dhis.reportsheet.cogroup.action.UpdateSortedCategoryOptionGroupOrderAction">
+			<result name="success" type="velocity-json">
+				/dhis-web-commons/ajax/jsonResponseSuccess.vm</result>
+		</action>
+		
+		<action name="getCategoryOptionGroupOrder"
+			class="org.hisp.dhis.reportsheet.cogroup.action.GetCategoryOptionGroupOrderAction">
+			<result name="success" type="velocity-json">
+				/dhis-web-spreadsheet-reporting/jsonCategoryOptionGroupOrder.vm</result>
+		</action>
+		
+		<action name="openSortCategoryOption"
+			class="org.hisp.dhis.reportsheet.cogroup.action.GetCategoryOptionGroupOrderAction">
+			<result name="success" type="velocity">/main.vm</result>
+			<param name="page">/dhis-web-spreadsheet-reporting/sortCategoryOptions.vm</param>
+			<param name="menu">/dhis-web-spreadsheet-reporting/menu.vm</param>
+			<param name="javascripts">javascript/categoryOptionGroupOrder.js</param>
+			<param name="stylesheets">style/basic.css</param>
+		</action>
+
+		<action name="updateSortedCategoryOptionsForExportReport"
+			class="org.hisp.dhis.reportsheet.cogroup.action.UpdateSortedCategoryOptionAction">
+			<result name="success" type="redirect">
+				listCategoryOptionGroupOrderForExportReport.action?id=${reportId}</result>
+		</action>
+		
+		<action name="updateSortedCategoryOptionsForImportReport"
+			class="org.hisp.dhis.reportsheet.cogroup.action.UpdateSortedCategoryOptionAction">
+			<result name="success" type="redirect">
+				listCategoryOptionGroupOrderForImportReport.action?id=${reportId}</result>
+		</action>		
+
+		<action name="getCategoryOptionsByCategory"
+			class="org.hisp.dhis.reportsheet.cogroup.action.GetCategoryOptionsByCategoryAction">
+			<result name="success" type="velocity-json">
+				/dhis-web-spreadsheet-reporting/jsonCategoryOptions.vm</result>
+			<param name="onExceptionReturn">plainTextError</param>
+		</action>
 
 		<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
 		<!-- DATAELEMENT GROUP ORDER FOR CATEGORY ACTION 				   -->
@@ -208,7 +310,7 @@
 			<param name="page">/dhis-web-spreadsheet-reporting/listDataElementGroupOrder.vm</param>
 			<param name="menu">/dhis-web-spreadsheet-reporting/menu.vm</param>
 			<param name="javascripts">javascript/dataElementGroupOrder.js</param>
-			<param name="stylesheets">style/basic.css, style/style.css</param>
+			<param name="stylesheets">style/basic.css,style/style.css</param>
 		</action>	
 		
 		<action name="validateDataElementGroupOrder"
@@ -377,7 +479,7 @@
 			class="org.hisp.dhis.reportsheet.avgroup.action.UpdateSortedAttributeValueAction">
 			<result name="success" type="redirect">
 				listAttributeValueGroupOrderForImportReport.action?id=${reportId}</result>
-		</action>		
+		</action>
 
 		<action name="getAttributeValuesByAttribute"
 			class="org.hisp.dhis.reportsheet.avgroup.action.GetAttributeValuesByAttributeAction">

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/attributeValueGroupOrder.js'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/attributeValueGroupOrder.js	2012-04-16 03:00:30 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/attributeValueGroupOrder.js	2012-04-26 18:25:07 +0000
@@ -1,16 +1,5 @@
 var selectedAttributeValueMap = new Array();
 
-function addOptionToListWithToolTip( list, optionValue, optionText )
-{
-    var option = document.createElement( "option" );
-    option.value = optionValue;
-    option.text = optionText;
-	option.onmousemove = function(e) {
-		showToolTip(e, optionText);
-	}
-    list.add( option, null );
-}
-
 function showAttributeValueGroupOrderDetails( id )
 {
 	jQuery.post( 'getAttributeValueGroupOrder.action',  { id: id }, function( json ) {
@@ -152,37 +141,4 @@
 	moveAllById( 'availableList', 'selectedList' );
 	selectAllById( 'selectedList' );
 	document.forms[0].submit();
-}
-
-/*
-*	Tooltip
-*/
-function showToolTip( e, value)
-{	
-	var tooltipDiv = byId( 'tooltip' );
-	tooltipDiv.style.display = 'block';
-	
-	var posx = 0;
-    var posy = 0;
-	
-    if (!e) var e = window.event;
-    if (e.pageX || e.pageY)
-    {
-        posx = e.pageX;
-        posy = e.pageY;
-    }
-    else if (e.clientX || e.clientY)
-    {
-        posx = e.clientX;
-        posy = e.clientY;
-    }
-	
-	tooltipDiv.style.left= posx  + 8 + 'px';
-	tooltipDiv.style.top = posy  + 8 + 'px';
-	tooltipDiv.innerHTML = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" +   value;
-}
-
-function hideToolTip()
-{
-	byId('tooltip').style.display = 'none';
 }
\ No newline at end of file

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/category.ajax.js'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/category.ajax.js	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/category.ajax.js	2012-04-26 18:25:07 +0000
@@ -0,0 +1,133 @@
+
+function CategoryLib()
+{
+	var categoryMap = new Array();
+	var categoryOptionMap = new Array();
+	
+	this.loadCategories = function( elementId, id )
+	{
+		var target = jQuery( "#" + elementId );
+		target.children().remove();
+
+		if ( categoryMap.length == 0 )
+		{	
+			jQuery.getJSON( '../dhis-web-commons-ajax-json/getDataElementCategories.action', function( json )
+			{
+				categoryMap.push( new Category( -1, '[ ' + i18n_label + ' ]' ) );
+				target.append( '<option value="-1">[ ' + i18n_label + ' ]</option>' );
+				
+				jQuery.each( json.dataElementCategories, function( i, item )
+				{
+					if ( id && item.id == id ) {
+						target.append( '<option value="' + item.id + '" selected="true">' + item.name + '</option>' );
+					}
+					else {
+						target.append( '<option value="' + item.id + '">' + item.name + '</option>' );
+					}
+					
+					categoryMap.push( new Category( item.id, item.name ) );
+				} );
+			} );
+		}
+		else
+		{
+			jQuery.each( categoryMap, function( i, item )
+			{
+				if ( id && item.id == id ) {
+					target.append( '<option value="' + item.id + '" selected="true">' + item.name + '</option>' );
+				}
+				else {
+					target.append( '<option value="' + item.id + '">' + item.name + '</option>' );
+				}
+			} );
+		}
+	};
+
+	this.loadCategoryOptionsByCategory = function( id, curItems, sourceList, destList, isFirstLoad )
+	{
+		var source = jQuery( "#" + sourceList );
+		var dest = jQuery( "#" + destList );
+		
+		if ( source )
+		{
+			source.empty();
+		}
+
+		if ( dest && !isFirstLoad )
+		{
+			dest.empty();
+		}
+
+		var valueList = categoryOptionMap[ id ];
+
+		if ( valueList == null )
+		{
+			valueList = new Array();
+
+			jQuery.getJSON( 'getCategoryOptionsByCategory.action', {
+				categoryId : id
+			}, function( json )
+			{
+				jQuery.each( json.categoryOptions, function( i, item )
+				{
+					valueList.push( new CategoryOption( item.id, item.name ) );
+					source.append( '<option value="' + item.id + '">' + item.name + '</option>' );
+				} );
+				
+				categoryOptionMap[ id ] = valueList;
+			} );
+		}
+		else
+		{
+			jQuery.each( valueList, function( i, item )
+			{
+				source.append( '<option value="' + item.id + '">' + item.name + '</option>' );
+			} );
+		}
+
+		if ( curItems )
+		{
+			jQuery.each( curItems, function( i, item )
+			{
+				dest.append( '<option value="' + item.value + '">' + item.value + '</option>' );
+			} );
+		}
+		
+		this.removeDuplicatedItem( sourceList, destList );
+	};
+	
+	this.removeDuplicatedItem = function( availableList, selectedList )
+	{
+		var $list1 = jQuery('#' + availableList);
+		var $list2 = jQuery('#' + selectedList);
+		
+		if ( $list1 && $list2 )
+		{
+			jQuery.each( $list2.children(), function( i, item )
+			{
+				$list1.find( "option[value='" + item.value + "']" ).remove();
+			} );
+		}		
+	};
+
+	this.resetParams = function()
+	{
+		this.categoryMap = new Array();
+		this.categoryOptionMap = new Array();
+	}
+}
+
+
+function Category( _id, _name )
+{
+	this.id = _id;
+	this.name = _name;
+}
+
+function CategoryOption( _id, _name )
+{
+	this.id = _id;
+	this.name = _name;
+}
+
+var categoryLib = new CategoryLib();
\ No newline at end of file

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/categoryOptionGroupOrder.js'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/categoryOptionGroupOrder.js	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/categoryOptionGroupOrder.js	2012-04-26 18:25:07 +0000
@@ -0,0 +1,143 @@
+var selectedCategoryOptionMap = new Array();
+
+function showCategoryOptionGroupOrderDetails( id )
+{
+	jQuery.post( 'getCategoryOptionGroupOrder.action', { id: id }, function( json ) {
+		
+		setInnerHTML( 'nameField', json.categoryOptionGroupOrder.name );
+		setInnerHTML( 'memberCountField', json.categoryOptionGroupOrder.memberCount );
+
+		showDetails();
+	});
+}
+
+function resetForm()
+{
+	setFieldValue( "name", "" );
+	setFieldValue( "categoryOptionGroupOrderId", "" );
+
+	var availableList = jQuery( '#availableCategoryOptions' );
+	availableList.empty();
+	var selectedList = jQuery( '#categoryOptions' );
+	selectedList.empty();
+}
+
+/*
+* 	Open Add Category Option Group Order 
+*/
+function openAddCategoryOptionGroupOrder()
+{
+	resetForm();
+	validator.resetForm();
+
+	categoryLib.loadCategories( "categoryId" );
+
+	dialog.dialog("open");
+	
+	jQuery( "#categoryOptionGroupsForm" ).attr( "action", "addCategoryOptionGroupOrderFor" + clazzName + ".action?clazzName=" + clazzName );
+}
+
+/*
+* 	Open Update Category Option Order
+*/
+
+function openUpdateCategoryOptionGroupOrder( id )
+{
+	validator.resetForm();
+	setFieldValue("categoryOptionGroupOrderId", id );
+	
+	jQuery.post( 'getCategoryOptionGroupOrder.action', { id: id }, function( json )
+	{
+		var categoryOptions = json.categoryOptionGroupOrder.categoryOptions;
+		var categoryId = ( categoryOptions.length > 0 ? categoryOptions[ 0 ].categoryId : "" );
+		var list = jQuery( "#categoryOptions" );
+		list.empty();
+		selectedCategoryOptionMap = [];
+		var items = [];
+		
+		setFieldValue( "name", json.categoryOptionGroupOrder.name );
+		categoryLib.loadCategories( "categoryId", categoryId );
+		categoryLib.loadCategoryOptionsByCategory( categoryId, items, "availableCategoryOptions", "categoryOptions", true );
+		
+		for ( var i = 0 ; i < categoryOptions.length ; i++ )
+		{
+			items.push( new CategoryOption( categoryOptions[ i ].id, categoryOptions[ i ].name ) );
+			list.append( '<option value="' + categoryOptions[ i ].id + '">' + categoryOptions[ i ].name + '</option>' );
+		}
+
+		selectedCategoryOptionMap[ id + "-" + categoryId ] = items;
+
+		categoryLib.removeDuplicatedItem( "availableCategoryOptions", "categoryOptions" );
+
+		jQuery( "#categoryOptionGroupsForm" ).attr( "action", "updateCategoryOptionGroupOrderFor" + clazzName + ".action" );
+		dialog.dialog( "open" );
+	} );
+}
+
+function validateCategoryOptionGroupOrder( _form )
+{
+	var categoryId = getFieldValue( "categoryId" );
+
+	if ( categoryId && categoryId != -1 )
+	{
+		jQuery.postUTF8( "validateCategoryOptionGroupOrder.action", {
+			name: getFieldValue( 'name' ),
+			id: getFieldValue( 'categoryOptionGroupOrderId' ),
+			reportId: reportId,
+			clazzName: clazzName
+		}, function( json )
+		{
+			if ( json.response == "success" )
+			{
+				if ( hasElements( 'categoryOptions' ) )
+				{
+					selectAllById( 'categoryOptions' );
+					_form.submit();
+				}
+				else { markInvalid( "categoryOptions", i18n_selected_list_empty ); }
+			}
+			else { markInvalid( "name", json.message ); }
+		} );
+	} else { markInvalid( "categoryId", i18n_verify_category ); }
+}
+
+/*
+* 	Delete Category Option Group Order
+*/
+function deleteCategoryOptionGroupOrder( id, name )
+{
+	removeItem( id, name, i18n_confirm_delete, 'deleteCategoryOptionGroupOrder.action', function(){ window.location.reload(); } );
+}
+
+/*
+*	Update Category Option Group Order
+*/
+function updateSortCategoryOptionGroupOrder()
+{
+	var categoryOptionGroups = document.getElementsByName( 'categoryOptionGroupOrder' );
+	var url = "updateSortCategoryOptionGroupOrder.action?reportId=" + reportId + "&clazzName=" + clazzName;
+	
+	for ( var i = 0 ; i < categoryOptionGroups.length ; i++ )
+	{
+		url += "&categoryOptionGroupOrderId=" + categoryOptionGroups.item(i).value;
+	}
+	
+	jQuery.get( url, {}, function( json ) {
+		showSuccessMessage( json.message );
+	});
+}
+
+function openSortCategoryOptionForGroupOrder( id )
+{
+	window.location = "openSortCategoryOption.action?id="+id+"&reportId="+reportId+"&clazzName="+clazzName;
+}
+
+/*
+* 	Update Sorted Category Option
+*/
+function updateSortedCategoryOption()
+{	
+	moveAllById( 'availableList', 'selectedList' );
+	selectAllById( 'selectedList' );
+	document.forms[0].submit();
+}
\ No newline at end of file

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/dataElementGroupOrder.js'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/dataElementGroupOrder.js	2011-12-13 07:46:57 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/dataElementGroupOrder.js	2012-04-26 18:25:07 +0000
@@ -1,15 +1,3 @@
-
-function addOptionToListWithToolTip( list, optionValue, optionText )
-{
-    var option = document.createElement( "option" );
-    option.value = optionValue;
-    option.text = optionText;
-	option.onmousemove = function(e) {
-		showToolTip(e, optionText);
-	}
-    list.add( option, null );
-}
-
 function showDataElementGroupOrderDetails( id )
 {
 	jQuery.post( 'getDataElementGroupOrder.action',  { id: id }, function( json ) {

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/exportItems.js'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/exportItems.js	2012-04-25 09:59:24 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/exportItems.js	2012-04-26 18:25:07 +0000
@@ -57,6 +57,8 @@
 	{
 		if ( attribute ) {
 			byId('expression-button' ).onclick = avExpressionBuilderForm;
+		} else if ( categoryVertical ) {
+			byId('expression-button' ).onclick = coExpressionBuilderForm;
 		} else {
 			byId('expression-button' ).onclick = deExpressionBuilderForm;
 		}
@@ -92,18 +94,22 @@
 	var expression = '';
 
 	if ( attribute ) {
-		expression = "[" + getFieldValue( "groupSelect" ) + "@" + getFieldValue( "elementSelect" ) + "]";
+		expression = "[" + getFieldValue( "attributevalue [id=groupSelect]" ) + "@" + getFieldValue( "attributevalue [id=elementSelect]" ) + "]";
+		setFieldValue( 'attributevalue [id=formula]', getFieldValue( 'attributevalue [id=formula]' ) + expression );
 	}
 	else if ( category ) {
-		expression = "[*." + getFieldValue( "elementSelect" )+ "]";
+		expression = "[*." + getFieldValue( "dataelement [id=elementSelect]" )+ "]";
+		setFieldValue( 'dataelement [id=formula]', getFieldValue( 'dataelement [id=formula]' ) + expression );
+	}
+	else if ( categoryVertical ) {
+		expression = "[*." + getFieldValue( "categoryoption [id=elementSelect]" )+ "]";
+		setFieldValue( 'categoryoption [id=formula]', getFieldValue( 'categoryoption [id=formula]' ) + expression );
 	}
 	else {
-		expression = getFieldValue( "elementSelect" );
-		alert(expression);
+		expression = getFieldValue('dataelement [id=elementSelect]');
+		setFieldValue( 'dataelement [id=formula]', getFieldValue( 'dataelement [id=formula]' ) + expression );
 	}
 
-	setFieldValue( 'formula', getFieldValue( 'formula' ) + expression );
-
 	if ( !attribute ) { getExpression(); }
 }
 

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/grouporder.tooltip.js'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/grouporder.tooltip.js	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/grouporder.tooltip.js	2012-04-26 18:25:07 +0000
@@ -0,0 +1,44 @@
+/*
+*	Tooltip
+*/
+
+function addOptionToListWithToolTip( list, optionValue, optionText )
+{
+    var option = document.createElement( "option" );
+    option.value = optionValue;
+    option.text = optionText;
+	option.onmousemove = function(e) {
+		showToolTip(e, optionText);
+	}
+    list.add( option, null );
+}
+
+function showToolTip( e, value)
+{	
+	var tooltipDiv = byId( 'tooltip' );
+	tooltipDiv.style.display = 'block';
+	
+	var posx = 0;
+    var posy = 0;
+	
+    if (!e) var e = window.event;
+    if (e.pageX || e.pageY)
+    {
+        posx = e.pageX;
+        posy = e.pageY;
+    }
+    else if (e.clientX || e.clientY)
+    {
+        posx = e.clientX;
+        posy = e.clientY;
+    }
+	
+	tooltipDiv.style.left= posx  + 8 + 'px';
+	tooltipDiv.style.top = posy  + 8 + 'px';
+	tooltipDiv.innerHTML = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" +   value;
+}
+
+function hideToolTip()
+{
+	byId('tooltip').style.display = 'none';
+}
\ No newline at end of file

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/jsonCategoryOptionGroupOrder.vm'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/jsonCategoryOptionGroupOrder.vm	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/jsonCategoryOptionGroupOrder.vm	2012-04-26 18:25:07 +0000
@@ -0,0 +1,18 @@
+{ "categoryOptionGroupOrder":
+  {
+    "name": "$!encoder.jsonEncode( ${categoryOptionGroupOrder.name} )",
+	
+	#set( $size = ${categoryOptionGroupOrder.categoryOptions.size()} )
+	"memberCount": "${size}",
+
+	"categoryOptions": [
+	#foreach( $co in $!categoryOptionGroupOrder.categoryOptions )
+	{
+	  "id": "${co.id}",
+	  "name": "$!encoder.jsonEncode( ${co.name} )",
+	  "categoryId": "${co.category.id}"
+	}#if( $velocityCount < $size ),#end
+	#end
+	]
+  }
+}
\ No newline at end of file

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/jsonCategoryOptions.vm'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/jsonCategoryOptions.vm	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/jsonCategoryOptions.vm	2012-04-26 18:25:07 +0000
@@ -0,0 +1,12 @@
+#set( $size = $!categoryOptions.size() )
+{
+	"categoryOptions": [
+	#foreach( $co in $!categoryOptions )
+	{
+	  "id": "${co.id}",
+	  "name": "$!encoder.jsonEncode( ${co.name} )",
+	  "categoryId": "${co.category.id}"
+	}#if( $velocityCount < $size ),#end
+	#end
+	]
+}
\ No newline at end of file

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/listCategoryOptionGroupOrder.vm'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/listCategoryOptionGroupOrder.vm	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/listCategoryOptionGroupOrder.vm	2012-04-26 18:25:07 +0000
@@ -0,0 +1,134 @@
+<script type="text/javascript">
+	var validator = null;
+
+	jQuery(document).ready( function()
+	{
+		validator = validation( "categoryOptionGroupsForm", function( form ) { validateCategoryOptionGroupOrder( form ); });
+	} );
+</script>
+<h3>$i18n.getString( 'categoryoption_groups' )</h3>
+<h4><font color="green">$!encoder.htmlEncode( $!report.displayName )</font></h4>
+<table width="800px">
+	<tr>
+		<td colspan=2>
+			<input type="button" onclick="javascript:openAddCategoryOptionGroupOrder();" value="$i18n.getString('add')" style="width:100px"/>
+			<input type="button" value="$i18n.getString( 'cancel' )" onclick="window.location='listAll${clazzSimpleName}.action'" style="width:100px"/>
+		</td>
+		<td width="100px">
+			<input type="button" value="$i18n.getString( 'update_order' )" onclick="javascript:updateSortCategoryOptionGroupOrder();" style="width:150px"/>
+		</td>
+	</tr>
+	<tr>
+		<th colspan=2>$i18n.getString('name')</th>
+		<th width="100px">$i18n.getString('operations')</th>		
+	</tr>	
+</table>
+
+<table align="right">
+	<tr>
+		<td style="width:20em; padding-left:2em; vertical-align:top">
+			<div id="detailsArea" style="display:none">
+				<div style="float:right">
+					<a href="javascript:hideDetails()" title="$i18n.getString( 'hide_details' )"><img src="../images/close.png" alt="$i18n.getString( 'hide_details' )"/></a>
+				</div>				
+				<p><label>$i18n.getString( "name" ):</label><br/><span id="nameField"></span></p>
+				<p><label>$i18n.getString( "number_of_members" ):</label><br/><span id="memberCountField"></span></p>
+			</div>
+
+			<div id="warningArea" style="position:fixed;right:10px;top:200px;display:none">
+				<div style="float:right">
+					<a href="javascript:hideWarning()" title="$i18n.getString( 'hide_warning' )"><img src="../images/close.png" alt="$i18n.getString( 'hide_warning' )"/></a>
+				</div>
+				<p><span id="warningField"></span></p>
+			</div>
+		</td>
+	</tr>
+</table>
+
+<ul id="sortable"> 
+#foreach( $group in $!report.categoryOptionOrders )
+	<li class="ui-state-default" name="categoryOptionGroupOrder" value="$group.id" title="$i18n.getString( 'sort_order_help' )">		
+		<table cellspacing="0" cellpadding="0" width="100%">
+			<tr>
+				<td width="625px">$!encoder.htmlEncode( $group.name )</td>
+				<td>
+					<a href="javascript:deleteCategoryOptionGroupOrder( '$group.id', '$group.name' );" title="$i18n.getString( 'remove' )"><img src="../images/delete.png" alt="$i18n.getString( 'remove' )"/></a>
+					<a href="javascript:openUpdateCategoryOptionGroupOrder( '$group.id' );" title="$i18n.getString( 'edit' )"><img src="../images/edit.png" alt="$i18n.getString( 'edit' )"/></a>
+					<a href="javascript:openSortCategoryOptionForGroupOrder( '$group.id' );" title="$i18n.getString( 'sort_categoryoption' )"><img src="../images/sort.png" border="1px"/></a>
+					<a href="javascript:showCategoryOptionGroupOrderDetails( '$group.id' );" title="$i18n.getString( 'show_details' )"><img src="../images/information.png" border="1px" alt="$i18n.getString( 'show_details' )"/></a>
+				</td>
+			</tr>
+		</table>
+	</li> 	
+#end
+</ul>
+
+<div id="categoryOptionGroups">
+	<form name="categoryOptionGroupsForm" id="categoryOptionGroupsForm" method="POST">
+		<input type="hidden" name="id" value="$report.id"/>
+		<input type="hidden" name="categoryOptionGroupOrderId" id="categoryOptionGroupOrderId"/>
+		<table>
+			<tr>
+				<td>$i18n.getString('name')</td>
+				<td><input type="text" style="width:400px" id="name" name="name" class="{validate:{required:true}}"/></td>
+			</tr>
+		</table>		
+		<br/>		
+		<table width="100%">		
+			<tr>
+				<td colspan="4">
+					<select id="categoryId" name="categoryId" 
+					onchange="javascript:categoryLib.loadCategoryOptionsByCategory( this.value , selectedCategoryOptionMap[ byId( 'categoryOptionGroupOrderId' ).value + '-' + this.value ], 'availableCategoryOptions', 'categoryOptions', false );"
+					style="width:300px"></select>
+				</td>
+			</tr>
+			<tr>
+				<td width="23%">
+					<select id="availableCategoryOptions" name="availableCategoryOptions" multiple="true" size="13" style="width:300px" ondblclick="javascript:moveSelectedById('availableCategoryOptions','categoryOptions');"></select>
+				</td>
+				<td width="7%" align="center">
+					<input type="button" value="&gt;" onclick="javascript:moveSelectedById('availableCategoryOptions','categoryOptions');" style="width:50px"/><br/>
+					<input type="button" value="&lt;" onclick="javascript:moveSelectedById('categoryOptions' , 'availableCategoryOptions' );" style="width:50px"/><br/>
+					<input type="button" value="&gt;&gt;" onclick="javascript:moveAllById('availableCategoryOptions' , 'categoryOptions' );" style="width:50px"/><br/>
+					<input type="button" value="&lt;&lt;" onclick="javascript:moveAllById('categoryOptions' , 'availableCategoryOptions' );" style="width:50px"/>
+				</td>
+				<td width="23%">
+					<select id="categoryOptions" name="categoryOptions" multiple="true" size="13" style="width:300px" ondblclick="moveSelectedById('categoryOptions', 'availableCategoryOptions' )"></select>
+				</td>
+				<td width="47%"><a href="javascript:moveSelectedOptionToTop( 'categoryOptions' );"><img src="../images/move_top.png" style="cursor: pointer; width: 20px;" align="absmiddle"/></a><br/><br/>
+					<a href="javascript:moveUpSelectedOption( 'categoryOptions' );"><img src="../images/move_up.png" style="cursor: pointer; width: 20px;" align="absmiddle"/></a><br/><br/>
+					<a href="javascript:moveDownSelectedOption( 'categoryOptions' );"><img src="../images/move_down.png" style="cursor: pointer; width: 20px;" align="absmiddle"/></a><br/><br/>
+					<a href="javascript:moveSelectedOptionToBottom( 'categoryOptions' );"><img src="../images/move_bottom.png" style="cursor: pointer; width: 20px;" align="absmiddle"/></a>
+				</td>
+			</tr>
+		</table>
+
+	<p align="center">
+	<input type="submit" value="$i18n.getString( 'save' )" style="width:130px"/>		
+	<input type="button" value="$i18n.getString( 'cancel' )" style="width:130px" onclick="dialog.dialog('close')"/>		
+	</p>
+	</form>
+</div>
+
+<div id="tooltip"></div>
+
+<script>
+	var i18n_confirm_delete = '$encoder.jsEscape($i18n.getString( 'confirm_delete' ) , "'")';
+	var i18n_name_is_null = '$encoder.jsEscape($i18n.getString( 'i18n_name_is_null' ) , "'")';
+	var i18n_label = '$encoder.jsEscape($i18n.getString( 'select_category' ) , "'")';
+	var i18n_verify_category = '$encoder.jsEscape($i18n.getString( 'please_select_category' ) , "'")';
+	var i18n_selected_list_empty = '$encoder.jsEscape($i18n.getString( 'selected_list_should_not_empty' ) , "'")';
+
+	var reportId = ${report.id};
+	var clazzName = '${clazzSimpleName}';
+	
+	$(function() {
+		$("#sortable").sortable({
+			placeholder: 'ui-state-highlight'
+		});
+		$("#sortable").disableSelection();
+		
+	});
+	
+	var dialog = jQuery("#categoryOptionGroups").dialog( { modal:true,autoOpen:false,width:720,title:"$i18n.getString('categoryoption_groups')" } );
+</script>
\ No newline at end of file

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/report/addExportItemForm.vm'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/report/addExportItemForm.vm	2012-04-25 09:59:24 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/report/addExportItemForm.vm	2012-04-26 18:25:07 +0000
@@ -6,8 +6,9 @@
 		});
 	});
 	
+	var attribute = $!exportReport.isAttribute();
 	var category = $!exportReport.isCategory();
-	var attribute = $!exportReport.isAttribute();
+	var categoryVertical = $!exportReport.isCategoryVertical();
 	
 </script>
 
@@ -99,10 +100,24 @@
 
 <!-- EXPRESSION FORM -->
 
-#parse( "/dhis-web-spreadsheet-reporting/report/attributeValueExpressionBuilderForm.vm" )
-
-#parse( "/dhis-web-spreadsheet-reporting/report/dataelementExpressionBuilderForm.vm" )
-
-#parse( "/dhis-web-spreadsheet-reporting/report/indicatorExpressionBuilderForm.vm" )
-
-#parse( "/dhis-web-spreadsheet-reporting/report/excelFormulaExpressionBuilderForm.vm" )
\ No newline at end of file
+
+#if ( $!exportReport.isAttribute() )
+	#parse( "/dhis-web-spreadsheet-reporting/report/attributeValueExpressionBuilderForm.vm" )
+
+#elseif ( $!exportReport.isCategory() )
+	#parse( "/dhis-web-spreadsheet-reporting/report/dataelementExpressionBuilderForm.vm" )
+	#parse( "/dhis-web-spreadsheet-reporting/report/excelFormulaExpressionBuilderForm.vm" )
+
+#elseif ( $!exportReport.isCategoryVertical() )
+	#parse( "/dhis-web-spreadsheet-reporting/report/categoryVerticalExpressionBuilderForm.vm" )
+	#parse( "/dhis-web-spreadsheet-reporting/report/excelFormulaExpressionBuilderForm.vm" )
+
+#elseif ( $!exportReport.isPeriodColumnListing() )
+	#parse( "/dhis-web-spreadsheet-reporting/report/dataelementExpressionBuilderForm.vm" )
+	#parse( "/dhis-web-spreadsheet-reporting/report/indicatorExpressionBuilderForm.vm" )
+
+#elseif ( $!exportReport.isNormal() || $!exportReport.isOrgUnitGroupListing() )
+	#parse( "/dhis-web-spreadsheet-reporting/report/dataelementExpressionBuilderForm.vm" )
+	#parse( "/dhis-web-spreadsheet-reporting/report/indicatorExpressionBuilderForm.vm" )
+	#parse( "/dhis-web-spreadsheet-reporting/report/excelFormulaExpressionBuilderForm.vm" )
+#end

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/report/categoryVerticalExpressionBuilderForm.vm'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/report/categoryVerticalExpressionBuilderForm.vm	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/report/categoryVerticalExpressionBuilderForm.vm	2012-04-26 18:25:07 +0000
@@ -0,0 +1,73 @@
+<script>
+	
+	jQuery(document).ready(function(){
+		coExpressionValidator = validation( 'categoryoption-form', function(){
+			updateCOExpression();
+		});
+		
+		coExpressionDialog = setUpDialog( 'categoryoption', i18n_expression, 800, 430 );
+		
+		//remoteValidate( jQuery( "#categoryoption textarea[id=formula]" ), 'checkAttributeValueValid.action' );
+		
+		changeItemType();
+	});
+
+	var coExpressionValidator = null;
+	var coExpressionDialog = null;
+	var i18n_no_dataelement_group = '$encoder.jsEscape( $i18n.getString( "no_dataelement_group" ) , "'")';;
+	var i18n_label = '$encoder.jsEscape($i18n.getString( 'select_dataelement_group' ) , "'")';
+</script>
+
+<div id="categoryoption" style="display:none">
+	<form id="categoryoption-form">
+	<table width="100%">
+		<tr>
+			<th>$i18n.getString( "formula" )</th>			
+			<th id="attributeOrderHeader">$i18n.getString( "categoryoption" )</th>
+		</tr>
+		<tr valign="top">
+			<td height="139">
+				<textarea id="formula" name="expression" cols="40" rows="5" class="{validate:{required:true}}"></textarea><br/>
+			</td>
+			<td>
+				<select id="groupSelect" style="width:500px" onchange="dataDictionary.loadDataElementsByGroup( this.value, 'categoryoption select[id=elementSelect]' )"></select>												
+				<select id="elementSelect" size="15" style="width:500px;" ondblclick="insertExpression()"></select>	
+			</td>			
+		</tr>
+		<tr>
+			<th colspan="2">$i18n.getString( "description" )</th>
+		<tr>	
+		<tr>
+			<td colspan="2">
+				<div id="expression-description" style="width:750px;height:30px;overflow:auto"></div>
+			</td>
+		</th>
+	</table>
+	<br/>
+	<br/>
+	<center>
+		<input type="submit" value="$i18n.getString('ok')" style="width:100px"/>
+		<input type="button" value="$i18n.getString('clean')" onclick="cleanFormula()" style="width:100px"/>
+		<input type="button" value="$i18n.getString('cancel')" onclick="closeDialog( coExpressionDialog )" style="width:100px"/>
+	</center>
+	</form>
+</div>
+
+<script>	
+	function coExpressionBuilderForm()
+	{
+		dataDictionary.loadDataElementGroups( "categoryoption select[id=groupSelect]" );
+		
+		setFieldValue( 'categoryoption textarea[id=formula]', getFieldValue( 'expression' ) );
+		getExpression();
+
+		openDialog( coExpressionDialog );
+	}
+	
+	function updateCOExpression()
+	{
+		expression = jQuery( '#categoryoption textarea[id=formula]' ).val();
+		setFieldValue( 'expression', expression );
+		closeDialog( coExpressionDialog );
+	}
+</script>
\ No newline at end of file

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/report/updateExportItemForm.vm'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/report/updateExportItemForm.vm	2012-04-25 09:59:24 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/report/updateExportItemForm.vm	2012-04-26 18:25:07 +0000
@@ -6,8 +6,10 @@
 		});
 	});
 	
+	var attribute = $!exportReport.isAttribute();
 	var category = $!exportReport.isCategory();
-	var attribute = $!exportReport.isAttribute();
+	var categoryVertical = $!exportReport.isCategoryVertical();
+
 </script>
 
 <h3>$i18n.getString( 'update_export_item' )</h3>
@@ -100,10 +102,23 @@
 
 <!-- EXPRESSION FORM -->
 
-#parse( "/dhis-web-spreadsheet-reporting/report/attributeValueExpressionBuilderForm.vm" )
-
-#parse( "/dhis-web-spreadsheet-reporting/report/dataelementExpressionBuilderForm.vm" )
-
-#parse( "/dhis-web-spreadsheet-reporting/report/indicatorExpressionBuilderForm.vm" )
-
-#parse( "/dhis-web-spreadsheet-reporting/report/excelFormulaExpressionBuilderForm.vm" )
+#if ( $!exportReport.isAttribute() )
+	#parse( "/dhis-web-spreadsheet-reporting/report/attributeValueExpressionBuilderForm.vm" )
+
+#elseif ( $!exportReport.isCategory() )
+	#parse( "/dhis-web-spreadsheet-reporting/report/dataelementExpressionBuilderForm.vm" )
+	#parse( "/dhis-web-spreadsheet-reporting/report/excelFormulaExpressionBuilderForm.vm" )
+
+#elseif ( $!exportReport.isCategoryVertical() )
+	#parse( "/dhis-web-spreadsheet-reporting/report/categoryVerticalExpressionBuilderForm.vm" )
+	#parse( "/dhis-web-spreadsheet-reporting/report/excelFormulaExpressionBuilderForm.vm" )
+
+#elseif ( $!exportReport.isPeriodColumnListing() )
+	#parse( "/dhis-web-spreadsheet-reporting/report/dataelementExpressionBuilderForm.vm" )
+	#parse( "/dhis-web-spreadsheet-reporting/report/indicatorExpressionBuilderForm.vm" )
+
+#elseif ( $!exportReport.isNormal() || $!exportReport.isOrgUnitGroupListing() )
+	#parse( "/dhis-web-spreadsheet-reporting/report/dataelementExpressionBuilderForm.vm" )
+	#parse( "/dhis-web-spreadsheet-reporting/report/indicatorExpressionBuilderForm.vm" )
+	#parse( "/dhis-web-spreadsheet-reporting/report/excelFormulaExpressionBuilderForm.vm" )
+#end
\ No newline at end of file

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/sortAttributeValues.vm'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/sortAttributeValues.vm	2012-04-16 03:00:30 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/sortAttributeValues.vm	2012-04-26 18:25:07 +0000
@@ -13,7 +13,7 @@
 		<td>
 			<select multiple size="30" id="availableList" name="availableList" style="min-width:300px;" ondblclick="moveSelectedById( 'availableList', 'selectedList' );">
 				#foreach( $attributeValue in $!attributeValueGroupOrder.attributeValues )
-    				<option value="$!attributeValue">$!attributeValue</option>
+    				<option value="$!attributeValue">$!encoder.htmlEncode( $!attributeValue )</option>
     			#end
 			</select>
 		</td>

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/sortCategoryOptions.vm'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/sortCategoryOptions.vm	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/sortCategoryOptions.vm	2012-04-26 18:25:07 +0000
@@ -0,0 +1,44 @@
+<h3>$i18n.getString( "sort_categoryoption" )</h3>
+<form action="updateSortedCategoryOptionsFor${clazzName}.action" method="POST">
+<input type="hidden" value="$!categoryOptionGroupOrder.id" name="id"/>
+<input type="hidden" value="$!reportId" name="reportId"/>
+<table>
+	<tr>
+  		<th>$i18n.getString( "available_categoryoptions" )</th>
+  		<td></td>
+  		<th>$i18n.getString( "selected_categoryoptions" )</th>
+		<td></td>
+	</tr>
+	<tr>		
+		<td>
+			<select multiple size="30" id="availableList" name="availableList" style="min-width:300px;" ondblclick="moveSelectedById( 'availableList', 'selectedList' );">
+				#foreach( $co in $!categoryOptionGroupOrder.categoryOptions )
+    				<option value="$!co.id">$!encoder.htmlEncode( $!co.name )</option>
+    			#end
+			</select>
+		</td>
+		<td style="text-align:center">
+			<input type="button" value="&gt;" title="$i18n.getString('move_selected')" style="width:50px" onclick="moveSelectedById( 'availableList', 'selectedList' );"/><br/>
+			<input type="button" value="&lt;" title="$i18n.getString('move_all')" style="width:50px" onclick="moveSelectedById( 'selectedList', 'availableList' );"/><br/>		
+			<input type="button" value="&gt;&gt;" title="$i18n.getString('remove_selected')" style="width:50px" onclick="moveAllById( 'availableList', 'selectedList' );"/><br/>
+			<input type="button" value="&lt;&lt;" title="$i18n.getString('remove_all')" style="width:50px" onclick="moveAllById( 'selectedList', 'availableList' );"/>
+		</td>
+		<td>
+			<select type="text" multiple size="30" id="selectedList" name="categoryOptions" style="min-width:300px;" ondblclick="moveSelectedById('selectedList','availableList');">
+			</select>
+		</td>	
+		<td>
+			<a href="javascript:moveSelectedOptionToTop( 'selectedList' );"><img align="absmiddle" src="../images/move_top.png" style="cursor:pointer;width:20px;"/></a><br/><br/>
+			<a href="javascript:moveUpSelectedOption( 'selectedList' );"><img align="absmiddle" src="../images/move_up.png" style="cursor:pointer;width:20px;"/></a><br/><br/>
+			<a href="javascript:moveDownSelectedOption( 'selectedList' );"><img align="absmiddle" src="../images/move_down.png" style="cursor:pointer;width:20px;"/></a><br/><br/>
+			<a href="javascript:moveSelectedOptionToBottom( 'selectedList' );"><img align="absmiddle" src="../images/move_bottom.png" style="cursor:pointer;width:20px;"/></a>
+		</td>
+	</tr>
+</table>
+
+<p>
+	<input type="button" value="$i18n.getString( 'ok' )" onclick="updateSortedCategoryOption();"/>
+	<input type="button" value="$i18n.getString( 'cancel' )" onclick="history.go(-1);"/>
+</p>
+
+<span id="message" style="top:100px;right:5px;position:fixed;width:200px;z-index:10002" onclick="javascript:hideById(this.id);"></span>
\ No newline at end of file