← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 6854: local vn - Allowed to assign the association between category option and organization unit.

 

------------------------------------------------------------
revno: 6854
committer: Hieu <hieu.hispvietnam@xxxxxxxxx>
branch nick: dhis2
timestamp: Fri 2012-05-04 16:50:39 +0700
message:
  local vn - Allowed to assign the association between category option and organization unit.
added:
  local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionAssociation.java
  local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionAssociationDeletionHandler.java
  local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionAssociationService.java
  local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionAssociationStore.java
  local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/hibernate/HibernateCategoryOptionAssociationStore.java
  local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/impl/DefaultCategoryOptionAssociationService.java
  local/vn/dhis-service-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/hibernate/CategoryOptionAssociation.hbm.xml
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/OpenCategoryOptionAssociationsAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/ShowDefineCategoryOptionAssociationsAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/UpdateCategoryOptionAssociationsAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/categoryOptionAssociations.vm
modified:
  local/vn/dhis-service-spreadsheet-reporting/src/main/resources/META-INF/dhis/beans.xml
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/AbstractGenerateMultiExcelReportSupport.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateMultiReportAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportAttributeAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportCategoryAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportNormalAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportOrgGroupListingAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportPeriodColumnListingAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportVerticalCategoryAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/resources/META-INF/dhis/beans.xml
  local/vn/dhis-web-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/i18n_module.properties
  local/vn/dhis-web-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/i18n_module_vi_VN.properties
  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/categoryOptionGroupOrder.js
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/listCategoryOptionGroupOrder.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/CategoryOptionAssociation.java'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionAssociation.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionAssociation.java	2012-05-04 09:50:39 +0000
@@ -0,0 +1,166 @@
+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 org.hisp.dhis.dataelement.DataElementCategoryOption;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public class CategoryOptionAssociation
+{
+    private int id;
+
+    private OrganisationUnit source;
+
+    private DataElementCategoryOption categoryOption;
+
+    // -------------------------------------------------------------------------
+    // Constructors
+    // -------------------------------------------------------------------------
+
+    public CategoryOptionAssociation()
+    {
+    }
+
+    public CategoryOptionAssociation( OrganisationUnit source, DataElementCategoryOption categoryOption )
+    {
+        this.source = source;
+        this.categoryOption = categoryOption;
+    }
+
+    // -------------------------------------------------------------------------
+    // Getters and setters
+    // -------------------------------------------------------------------------
+
+    public int getId()
+    {
+        return id;
+    }
+
+    public void setId( int id )
+    {
+        this.id = id;
+    }
+
+    public OrganisationUnit getSource()
+    {
+        return source;
+    }
+
+    public void setSource( OrganisationUnit source )
+    {
+        this.source = source;
+    }
+
+    public DataElementCategoryOption getCategoryOption()
+    {
+        return categoryOption;
+    }
+
+    public void setCategoryOption( DataElementCategoryOption categoryOption )
+    {
+        this.categoryOption = categoryOption;
+    }
+
+    // -------------------------------------------------------------------------
+    // hashCode and equals
+    // -------------------------------------------------------------------------
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+
+        result = prime * result + ((source == null) ? 0 : source.hashCode());
+        result = prime * result + ((categoryOption == null) ? 0 : categoryOption.hashCode());
+
+        return result;
+    }
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
+        {
+            return true;
+        }
+        if ( obj == null )
+        {
+            return false;
+        }
+        if ( getClass() != obj.getClass() )
+        {
+            return false;
+        }
+
+        CategoryOptionAssociation other = (CategoryOptionAssociation) obj;
+
+        if ( source == null )
+        {
+            if ( other.source != null )
+            {
+                return false;
+            }
+        }
+        else if ( !source.equals( other.source ) )
+        {
+            return false;
+        }
+
+        if ( categoryOption == null )
+        {
+            if ( other.categoryOption != null )
+            {
+                return false;
+            }
+        }
+        else if ( !categoryOption.equals( other.categoryOption ) )
+        {
+            return false;
+        }
+
+        if ( id != other.id )
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public String toString()
+    {
+        String toString = "[" + source + ", " + categoryOption + "]";
+
+        return toString;
+    }
+}

=== added file 'local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionAssociationDeletionHandler.java'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionAssociationDeletionHandler.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionAssociationDeletionHandler.java	2012-05-04 09:50:39 +0000
@@ -0,0 +1,80 @@
+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 org.hisp.dhis.dataelement.DataElementCategoryOption;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.system.deletion.DeletionHandler;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public class CategoryOptionAssociationDeletionHandler
+    extends DeletionHandler
+{
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    public CategoryOptionAssociationService categoryOptionAssociationService;
+
+    public void setCategoryOptionAssociationService( CategoryOptionAssociationService categoryOptionAssociationService )
+    {
+        this.categoryOptionAssociationService = categoryOptionAssociationService;
+    }
+
+    // -------------------------------------------------------------------------
+    // DeletionHandler implementation
+    // -------------------------------------------------------------------------
+
+    @Override
+    public String getClassName()
+    {
+        return CategoryOptionAssociation.class.getSimpleName();
+    }
+
+    @Override
+    public void deleteOrganisationUnit( OrganisationUnit unit )
+    {
+        for ( CategoryOptionAssociation registration : categoryOptionAssociationService
+            .getAllCategoryOptionAssociations() )
+        {
+            if ( registration.getSource().equals( unit ) )
+            {
+                categoryOptionAssociationService.deleteCategoryOptionAssociation( registration );
+            }
+        }
+    }
+    
+    @Override
+    public void deleteDataElementCategoryOption( DataElementCategoryOption categoryOption )
+    {
+        categoryOptionAssociationService.deleteCategoryOptionAssociations( categoryOption );
+    }
+}

=== added file 'local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionAssociationService.java'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionAssociationService.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionAssociationService.java	2012-05-04 09:50:39 +0000
@@ -0,0 +1,134 @@
+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.Collection;
+
+import org.hisp.dhis.dataelement.DataElementCategoryOption;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public interface CategoryOptionAssociationService
+{
+    String ID = CategoryOptionAssociationService.class.getName();
+
+    /**
+     * Saves a CategoryOptionAssociation.
+     * 
+     * @param association the CategoryOptionAssociation to save.
+     */
+    void saveCategoryOptionAssociation( CategoryOptionAssociation association );
+
+    /**
+     * Updates a CategoryOptionAssociation.
+     * 
+     * @param association the CategoryOptionAssociation to update.
+     */
+    void updateCategoryOptionAssociation( CategoryOptionAssociation association );
+
+    /**
+     * Deletes a CategoryOptionAssociation.
+     * 
+     * @param association the CategoryOptionAssociation to delete.
+     */
+    void deleteCategoryOptionAssociation( CategoryOptionAssociation association );
+
+    /**
+     * Deletes the CategoryOptionAssociations associated with the given
+     * OrganisationUnit.
+     * 
+     * @param source the OrganisationUnit.
+     */
+    void deleteCategoryOptionAssociations( OrganisationUnit source );
+
+    /**
+     * Deletes the CategoryOptionAssociations associated with the given
+     * DataElementCategoryOption.
+     * 
+     * @param categoryOption the DataElementCategoryOption.
+     */
+    void deleteCategoryOptionAssociations( DataElementCategoryOption categoryOption );
+
+    /**
+     * Deletes the CategoryOptionAssociations associated with the given
+     * DataElementCategoryOption and the list of OrganisationUnits.
+     * 
+     * @param categoryOption the DataElementCategoryOption.
+     * @param sources the list of OrganisationUnits.
+     */
+    void deleteCategoryOptionAssociations( Collection<OrganisationUnit> sources,
+        DataElementCategoryOption categoryOption );
+
+    /**
+     * Retrieves all CategoryOptionAssociations.
+     * 
+     * @return a Collection of CategoryOptionAssociations.
+     */
+    Collection<CategoryOptionAssociation> getAllCategoryOptionAssociations();
+
+    /**
+     * Retrieves all CategoryOptionAssociations associated with the given
+     * OrganisationUnit.
+     * 
+     * @param source the OrganisationUnit
+     * @return a Collection of CategoryOptionAssociations.
+     */
+    Collection<CategoryOptionAssociation> getCategoryOptionAssociations( OrganisationUnit source );
+
+    /**
+     * Retrieves the CategoryOptionAssociation for the given OrganisationUnit,
+     * DataElementCategoryOption
+     * 
+     * @param source the OrganisationUnit.
+     * @param categoryOption the DataElementCategoryOption.
+     * @return the CategoryOptionAssociation.
+     */
+    CategoryOptionAssociation getCategoryOptionAssociation( OrganisationUnit source,
+        DataElementCategoryOption categoryOption );
+
+    /**
+     * Retrieves all DataElementCategoryOptions associated with the given
+     * OrganisationUnit.
+     * 
+     * @param source the OrganisationUnit
+     * @return a Collection of DataElementCategoryOptions.
+     */
+    Collection<DataElementCategoryOption> getCategoryOptions( OrganisationUnit source );
+
+    /**
+     * Retrieves all OrganisationUnits associated with the given
+     * DataElementCategoryOption.
+     * 
+     * @param categoryOption the DataElementCategoryOption
+     * @return a Collection of OrganisationUnits.
+     */
+    Collection<CategoryOptionAssociation> getCategoryOptionAssociations( DataElementCategoryOption categoryOption );
+}

=== added file 'local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionAssociationStore.java'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionAssociationStore.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/CategoryOptionAssociationStore.java	2012-05-04 09:50:39 +0000
@@ -0,0 +1,134 @@
+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.Collection;
+
+import org.hisp.dhis.dataelement.DataElementCategoryOption;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public interface CategoryOptionAssociationStore
+{
+    String ID = CategoryOptionAssociationStore.class.getName();
+
+    /**
+     * Saves a CategoryOptionAssociation.
+     * 
+     * @param association the CategoryOptionAssociation to save.
+     */
+    void saveCategoryOptionAssociation( CategoryOptionAssociation association );
+
+    /**
+     * Updates a CategoryOptionAssociation.
+     * 
+     * @param association the CategoryOptionAssociation to update.
+     */
+    void updateCategoryOptionAssociation( CategoryOptionAssociation association );
+
+    /**
+     * Deletes a CategoryOptionAssociation.
+     * 
+     * @param association the CategoryOptionAssociation to delete.
+     */
+    void deleteCategoryOptionAssociation( CategoryOptionAssociation association );
+
+    /**
+     * Deletes the CategoryOptionAssociations associated with the given
+     * OrganisationUnit.
+     * 
+     * @param source the OrganisationUnit.
+     */
+    void deleteCategoryOptionAssociations( OrganisationUnit source );
+
+    /**
+     * Deletes the CategoryOptionAssociations associated with the given
+     * DataElementCategoryOption.
+     * 
+     * @param categoryOption the DataElementCategoryOption.
+     */
+    void deleteCategoryOptionAssociations( DataElementCategoryOption categoryOption );
+
+    /**
+     * Deletes the CategoryOptionAssociations associated with the given
+     * DataElementCategoryOption and the list of OrganisationUnits.
+     * 
+     * @param categoryOption the DataElementCategoryOption.
+     * @param sources the list of OrganisationUnits.
+     */
+    void deleteCategoryOptionAssociations( Collection<OrganisationUnit> sources,
+        DataElementCategoryOption categoryOption );
+
+    /**
+     * Retrieves all CategoryOptionAssociations.
+     * 
+     * @return a Collection of CategoryOptionAssociations.
+     */
+    Collection<CategoryOptionAssociation> getAllCategoryOptionAssociations();
+
+    /**
+     * Retrieves all CategoryOptionAssociations associated with the given
+     * OrganisationUnit.
+     * 
+     * @param source the OrganisationUnit
+     * @return a Collection of CategoryOptionAssociations.
+     */
+    Collection<CategoryOptionAssociation> getCategoryOptionAssociations( OrganisationUnit source );
+
+    /**
+     * Retrieves the CategoryOptionAssociation for the given OrganisationUnit,
+     * DataElementCategoryOption
+     * 
+     * @param source the OrganisationUnit.
+     * @param categoryOption the DataElementCategoryOption.
+     * @return the CategoryOptionAssociation.
+     */
+    CategoryOptionAssociation getCategoryOptionAssociation( OrganisationUnit source,
+        DataElementCategoryOption categoryOption );
+
+    /**
+     * Retrieves all DataElementCategoryOptions associated with the given
+     * OrganisationUnit.
+     * 
+     * @param source the OrganisationUnit
+     * @return a Collection of DataElementCategoryOptions.
+     */
+    Collection<DataElementCategoryOption> getCategoryOptions( OrganisationUnit source );
+
+    /**
+     * Retrieves all OrganisationUnits associated with the given
+     * DataElementCategoryOption.
+     * 
+     * @param categoryOption the DataElementCategoryOption
+     * @return a Collection of OrganisationUnits.
+     */
+    Collection<CategoryOptionAssociation> getCategoryOptionAssociations( DataElementCategoryOption categoryOption );
+}

=== added file 'local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/hibernate/HibernateCategoryOptionAssociationStore.java'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/hibernate/HibernateCategoryOptionAssociationStore.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/hibernate/HibernateCategoryOptionAssociationStore.java	2012-05-04 09:50:39 +0000
@@ -0,0 +1,162 @@
+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 java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.hibernate.Criteria;
+import org.hibernate.Query;
+import org.hibernate.SessionFactory;
+import org.hibernate.criterion.Restrictions;
+import org.hisp.dhis.dataelement.DataElementCategoryOption;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.reportsheet.CategoryOptionAssociation;
+import org.hisp.dhis.reportsheet.CategoryOptionAssociationStore;
+import org.hisp.dhis.system.util.ConversionUtils;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public class HibernateCategoryOptionAssociationStore
+    implements CategoryOptionAssociationStore
+{
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    private SessionFactory sessionFactory;
+
+    public void setSessionFactory( SessionFactory sessionFactory )
+    {
+        this.sessionFactory = sessionFactory;
+    }
+
+    // -------------------------------------------------------------------------
+    // Implementation
+    // -------------------------------------------------------------------------
+
+    public void saveCategoryOptionAssociation( CategoryOptionAssociation registration )
+    {
+        sessionFactory.getCurrentSession().save( registration );
+    }
+
+    public void updateCategoryOptionAssociation( CategoryOptionAssociation registration )
+    {
+        sessionFactory.getCurrentSession().update( registration );
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public Collection<CategoryOptionAssociation> getAllCategoryOptionAssociations()
+    {
+        return sessionFactory.getCurrentSession().createCriteria( CategoryOptionAssociation.class ).list();
+    }
+
+    public CategoryOptionAssociation getCategoryOptionAssociation( OrganisationUnit source,
+        DataElementCategoryOption categoryOption )
+    {
+        Criteria criteria = sessionFactory.getCurrentSession().createCriteria( CategoryOptionAssociation.class );
+
+        criteria.add( Restrictions.eq( "source", source ) );
+        criteria.add( Restrictions.eq( "categoryOption", categoryOption ) );
+
+        return (CategoryOptionAssociation) criteria.uniqueResult();
+    }
+
+    public void deleteCategoryOptionAssociation( CategoryOptionAssociation registration )
+    {
+        sessionFactory.getCurrentSession().delete( registration );
+        sessionFactory.getCurrentSession().flush();
+    }
+
+    public void deleteCategoryOptionAssociations( OrganisationUnit source )
+    {
+        String hql = "delete from CategoryOptionAssociation c where c.source = :source";
+
+        Query query = sessionFactory.getCurrentSession().createQuery( hql );
+
+        query.setEntity( "source", source );
+
+        query.executeUpdate();
+    }
+
+    public void deleteCategoryOptionAssociations( DataElementCategoryOption categoryOption )
+    {
+        String hql = "delete from CategoryOptionAssociation c where c.categoryOption = :categoryOption";
+
+        Query query = sessionFactory.getCurrentSession().createQuery( hql );
+
+        query.setEntity( "categoryOption", categoryOption );
+
+        query.executeUpdate();
+    }
+
+    @Override
+    public void deleteCategoryOptionAssociations( Collection<OrganisationUnit> sources,
+        DataElementCategoryOption categoryOption )
+    {
+        String hql = "delete from CategoryOptionAssociation c where c.categoryOption = :categoryOption and c.source.id in (:ids)";
+
+        Query query = sessionFactory.getCurrentSession().createQuery( hql );
+
+        query.setEntity( "categoryOption", categoryOption );
+        query.setParameterList( "ids", ConversionUtils.getIdentifiers( OrganisationUnit.class, sources ) );
+
+        query.executeUpdate();
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public Collection<CategoryOptionAssociation> getCategoryOptionAssociations( OrganisationUnit source )
+    {
+        Criteria criteria = sessionFactory.getCurrentSession().createCriteria( CategoryOptionAssociation.class );
+
+        criteria.add( Restrictions.eq( "source", source ) );
+
+        return criteria.list();
+    }
+
+    public Collection<DataElementCategoryOption> getCategoryOptions( OrganisationUnit source )
+    {
+        Set<DataElementCategoryOption> categoryOptions = new HashSet<DataElementCategoryOption>();
+
+        for ( CategoryOptionAssociation association : this.getCategoryOptionAssociations( source ) )
+        {
+            categoryOptions.add( association.getCategoryOption() );
+        }
+
+        return categoryOptions;
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public Collection<CategoryOptionAssociation> getCategoryOptionAssociations( DataElementCategoryOption categoryOption )
+    {
+        Criteria criteria = sessionFactory.getCurrentSession().createCriteria( CategoryOptionAssociation.class );
+
+        criteria.add( Restrictions.eq( "categoryOption", categoryOption ) );
+
+        return criteria.list();
+    }
+}

=== added file 'local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/impl/DefaultCategoryOptionAssociationService.java'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/impl/DefaultCategoryOptionAssociationService.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/impl/DefaultCategoryOptionAssociationService.java	2012-05-04 09:50:39 +0000
@@ -0,0 +1,125 @@
+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 java.util.Collection;
+
+import org.hisp.dhis.dataelement.DataElementCategoryOption;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.reportsheet.CategoryOptionAssociation;
+import org.hisp.dhis.reportsheet.CategoryOptionAssociationService;
+import org.hisp.dhis.reportsheet.CategoryOptionAssociationStore;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+@Transactional
+public class DefaultCategoryOptionAssociationService
+    implements CategoryOptionAssociationService
+{
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    private CategoryOptionAssociationStore categoryOptionAssociationStore;
+
+    public void setCategoryOptionAssociationStore( CategoryOptionAssociationStore categoryOptionAssociationStore )
+    {
+        this.categoryOptionAssociationStore = categoryOptionAssociationStore;
+    }
+
+    // -------------------------------------------------------------------------
+    // CategoryOptionAssociationService
+    // -------------------------------------------------------------------------
+
+    @Override
+    public void saveCategoryOptionAssociation( CategoryOptionAssociation association )
+    {
+        categoryOptionAssociationStore.saveCategoryOptionAssociation( association );
+    }
+
+    @Override
+    public void updateCategoryOptionAssociation( CategoryOptionAssociation association )
+    {
+        categoryOptionAssociationStore.updateCategoryOptionAssociation( association );
+    }
+
+    @Override
+    public void deleteCategoryOptionAssociation( CategoryOptionAssociation association )
+    {
+        categoryOptionAssociationStore.deleteCategoryOptionAssociation( association );
+    }
+
+    @Override
+    public void deleteCategoryOptionAssociations( OrganisationUnit source )
+    {
+        categoryOptionAssociationStore.deleteCategoryOptionAssociations( source );
+    }
+
+    @Override
+    public void deleteCategoryOptionAssociations( DataElementCategoryOption categoryOption )
+    {
+        categoryOptionAssociationStore.deleteCategoryOptionAssociations( categoryOption );
+    }
+
+    @Override
+    public void deleteCategoryOptionAssociations( Collection<OrganisationUnit> sources,
+        DataElementCategoryOption categoryOption )
+    {
+        categoryOptionAssociationStore.deleteCategoryOptionAssociations( sources, categoryOption );
+    }
+
+    @Override
+    public Collection<CategoryOptionAssociation> getAllCategoryOptionAssociations()
+    {
+        return categoryOptionAssociationStore.getAllCategoryOptionAssociations();
+    }
+
+    @Override
+    public Collection<CategoryOptionAssociation> getCategoryOptionAssociations( OrganisationUnit source )
+    {
+        return categoryOptionAssociationStore.getCategoryOptionAssociations( source );
+    }
+
+    @Override
+    public CategoryOptionAssociation getCategoryOptionAssociation( OrganisationUnit source,
+        DataElementCategoryOption categoryOption )
+    {
+        return categoryOptionAssociationStore.getCategoryOptionAssociation( source, categoryOption );
+    }
+
+    @Override
+    public Collection<DataElementCategoryOption> getCategoryOptions( OrganisationUnit source )
+    {
+        return categoryOptionAssociationStore.getCategoryOptions( source );
+    }
+
+    @Override
+    public Collection<CategoryOptionAssociation> getCategoryOptionAssociations( DataElementCategoryOption categoryOption )
+    {
+        return categoryOptionAssociationStore.getCategoryOptionAssociations( categoryOption );
+    }
+}

=== 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-29 09:57:26 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/resources/META-INF/dhis/beans.xml	2012-05-04 09:50:39 +0000
@@ -74,7 +74,7 @@
 	</bean>
 	
 	<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-	<!-- ATTRIBUTEVALUE-GROUP-ORDER STORE / SERVICE                    -->
+	<!-- CATEGORYOPTION-GROUP-ORDER STORE / SERVICE                    -->
 	<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
 	
 	<bean id="org.hisp.dhis.reportsheet.CategoryOptionGroupOrderStore"
@@ -87,6 +87,17 @@
 		<property name="categoryOptionGroupOrderStore"
 			ref="org.hisp.dhis.reportsheet.CategoryOptionGroupOrderStore" />
 	</bean>
+
+	<bean id="org.hisp.dhis.reportsheet.CategoryOptionAssociationStore"
+		class="org.hisp.dhis.reportsheet.hibernate.HibernateCategoryOptionAssociationStore">
+		<property name="sessionFactory" ref="sessionFactory"/>
+	</bean>
+	
+	<bean id="org.hisp.dhis.reportsheet.CategoryOptionAssociationService"
+		class="org.hisp.dhis.reportsheet.impl.DefaultCategoryOptionAssociationService">
+		<property name="categoryOptionAssociationStore"
+			ref="org.hisp.dhis.reportsheet.CategoryOptionAssociationStore" />
+	</bean>
 	
 	<!-- Report Location Manager -->
 
@@ -111,6 +122,12 @@
 			ref="org.hisp.dhis.reportsheet.importitem.ImportReportService" />
 	</bean>
 
+	<bean id="org.hisp.dhis.reportsheet.CategoryOptionAssociationDeletionHandler"
+		class="org.hisp.dhis.reportsheet.CategoryOptionAssociationDeletionHandler">
+		<property name="categoryOptionAssociationService"
+			ref="org.hisp.dhis.reportsheet.CategoryOptionAssociationService" />
+	</bean>
+
 	<!-- DeletionManager -->
 
 	<bean

=== added file 'local/vn/dhis-service-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/hibernate/CategoryOptionAssociation.hbm.xml'
--- local/vn/dhis-service-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/hibernate/CategoryOptionAssociation.hbm.xml	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-service-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/hibernate/CategoryOptionAssociation.hbm.xml	2012-05-04 09:50:39 +0000
@@ -0,0 +1,21 @@
+<?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.CategoryOptionAssociation" table="reportexcel_categoryoptionassociations">
+
+    <id name="id" column="categoryoptionassociationid">
+      <generator class="native" />
+    </id>
+
+    <properties name="source_categoryoption_unique_key" unique="true">
+      <many-to-one name="source" class="org.hisp.dhis.organisationunit.OrganisationUnit" column="sourceid"
+		foreign-key="fk_categoryoptionassociation_organisationunitid" />
+      <many-to-one name="categoryOption" class="org.hisp.dhis.dataelement.DataElementCategoryOption" column="categoryoptionid"
+		foreign-key="fk_categoryoptionassociation_categoryoptionid" />
+    </properties>
+
+  </class>
+</hibernate-mapping>

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/OpenCategoryOptionAssociationsAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/OpenCategoryOptionAssociationsAction.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/OpenCategoryOptionAssociationsAction.java	2012-05-04 09:50:39 +0000
@@ -0,0 +1,96 @@
+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 OpenCategoryOptionAssociationsAction
+    implements Action
+{
+    // -------------------------------------------------------------------------
+    // Dependency
+    // -------------------------------------------------------------------------
+
+    @Autowired
+    private CategoryOptionGroupOrderService groupOrderService;
+
+    // -------------------------------------------------------------------------
+    // Input & Output
+    // -------------------------------------------------------------------------
+
+    private Integer id;
+
+    private Integer reportId;
+
+    private CategoryOptionGroupOrder group;
+
+    // -------------------------------------------------------------------------
+    // Getter & Setter
+    // -------------------------------------------------------------------------
+
+    public void setId( Integer id )
+    {
+        this.id = id;
+    }
+
+    public void setReportId( Integer reportId )
+    {
+        this.reportId = reportId;
+    }
+
+    public Integer getReportId()
+    {
+        return reportId;
+    }
+
+    public CategoryOptionGroupOrder getGroup()
+    {
+        return group;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    public String execute()
+        throws Exception
+    {
+        group = groupOrderService.getCategoryOptionGroupOrder( id );
+
+        return SUCCESS;
+    }
+}

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/ShowDefineCategoryOptionAssociationsAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/ShowDefineCategoryOptionAssociationsAction.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/ShowDefineCategoryOptionAssociationsAction.java	2012-05-04 09:50:39 +0000
@@ -0,0 +1,100 @@
+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.HashSet;
+import java.util.Set;
+
+import org.hisp.dhis.dataelement.DataElementCategoryOption;
+import org.hisp.dhis.dataelement.DataElementCategoryService;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.oust.manager.SelectionTreeManager;
+import org.hisp.dhis.reportsheet.CategoryOptionAssociation;
+import org.hisp.dhis.reportsheet.CategoryOptionAssociationService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.opensymphony.xwork2.Action;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+
+public class ShowDefineCategoryOptionAssociationsAction
+    implements Action
+{
+    // -------------------------------------------------------------------------
+    // Dependency
+    // -------------------------------------------------------------------------
+
+    @Autowired
+    private DataElementCategoryService categoryService;
+
+    @Autowired
+    private CategoryOptionAssociationService associationService;
+
+    @Autowired
+    private SelectionTreeManager selectionTreeManager;
+
+    // -------------------------------------------------------------------------
+    // Input & Output
+    // -------------------------------------------------------------------------
+
+    private Integer categoryOptionId;
+
+    public void setCategoryOptionId( Integer categoryOptionId )
+    {
+        this.categoryOptionId = categoryOptionId;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    public String execute()
+        throws Exception
+    {
+        DataElementCategoryOption categoryOption = categoryService.getDataElementCategoryOption( categoryOptionId );
+
+        Set<OrganisationUnit> sources = new HashSet<OrganisationUnit>();
+
+        if ( categoryOption != null )
+        {
+            for ( CategoryOptionAssociation association : associationService
+                .getCategoryOptionAssociations( categoryOption ) )
+            {
+                sources.add( association.getSource() );
+            }
+        }
+        
+        selectionTreeManager.setSelectedOrganisationUnits( sources );
+
+        return SUCCESS;
+    }
+
+}

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/UpdateCategoryOptionAssociationsAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/UpdateCategoryOptionAssociationsAction.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/cogroup/action/UpdateCategoryOptionAssociationsAction.java	2012-05-04 09:50:39 +0000
@@ -0,0 +1,123 @@
+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.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.hisp.dhis.dataelement.DataElementCategoryOption;
+import org.hisp.dhis.dataelement.DataElementCategoryService;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.oust.manager.SelectionTreeManager;
+import org.hisp.dhis.reportsheet.CategoryOptionAssociation;
+import org.hisp.dhis.reportsheet.CategoryOptionAssociationService;
+import org.hisp.dhis.reportsheet.action.ActionSupport;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+
+public class UpdateCategoryOptionAssociationsAction
+    extends ActionSupport
+{
+    // -------------------------------------------------------------------------
+    // Dependency
+    // -------------------------------------------------------------------------
+
+    @Autowired
+    private DataElementCategoryService categoryService;
+
+    @Autowired
+    private CategoryOptionAssociationService associationService;
+
+    @Autowired
+    private SelectionTreeManager selectionTreeManager;
+
+    // -------------------------------------------------------------------------
+    // Input & Output
+    // -------------------------------------------------------------------------
+
+    private Integer categoryOptionId;
+
+    public void setCategoryOptionId( Integer categoryOptionId )
+    {
+        this.categoryOptionId = categoryOptionId;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action Implementation
+    // -------------------------------------------------------------------------
+
+    public String execute()
+        throws Exception
+    {
+        DataElementCategoryOption categoryOption = categoryService.getDataElementCategoryOption( categoryOptionId );
+
+        Set<OrganisationUnit> sources = new HashSet<OrganisationUnit>();
+
+        if ( categoryOption != null )
+        {
+            for ( CategoryOptionAssociation association : associationService
+                .getCategoryOptionAssociations( categoryOption ) )
+            {
+                sources.add( association.getSource() );
+            }
+        }
+
+        Set<OrganisationUnit> cloneSources = new HashSet<OrganisationUnit>( sources );
+
+        Collection<OrganisationUnit> selectedUnits = selectionTreeManager.getReloadedSelectedOrganisationUnits();
+
+        sources.removeAll( selectedUnits );
+
+        if ( sources != null && !sources.isEmpty() )
+        {
+            associationService.deleteCategoryOptionAssociations( sources, categoryOption );
+        }
+
+        selectedUnits.removeAll( cloneSources );
+
+        for ( OrganisationUnit newSource : selectedUnits )
+        {
+            CategoryOptionAssociation association = new CategoryOptionAssociation( newSource, categoryOption );
+            
+            associationService.saveCategoryOptionAssociation( association );
+        }
+        
+        sources = null;
+        cloneSources = null;
+        selectedUnits = null;
+        
+        message = i18n.getString( "update_associations_successful" );
+
+        return SUCCESS;
+    }
+}

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/AbstractGenerateMultiExcelReportSupport.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/AbstractGenerateMultiExcelReportSupport.java	2012-05-03 10:04:29 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/AbstractGenerateMultiExcelReportSupport.java	2012-05-04 09:50:39 +0000
@@ -33,6 +33,7 @@
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.period.Period;
 import org.hisp.dhis.period.PeriodType;
+import org.hisp.dhis.reportsheet.CategoryOptionAssociationService;
 import org.hisp.dhis.reportsheet.ExportReport;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -51,11 +52,14 @@
     // -------------------------------------------------------------------------
 
     @Autowired
+    protected OrganisationUnitService organisationUnitService;
+
+    @Autowired
+    protected CategoryOptionAssociationService categoryOptionAssociationService;
+
+    @Autowired
     protected LocalDataElementService localDataElementService;
 
-    @Autowired
-    protected OrganisationUnitService organisationUnitService;
-
     // -------------------------------------------------------------------------
     // Action implementation
     // -------------------------------------------------------------------------

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateMultiReportAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateMultiReportAction.java	2012-05-03 10:04:29 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateMultiReportAction.java	2012-05-04 09:50:39 +0000
@@ -130,8 +130,7 @@
                 {
                     ExportReportPeriodColumnListing reportInstance = (ExportReportPeriodColumnListing) report;
 
-                    this
-                        .generatePeriodListing( reportInstance.getPeriodColumns(), exportItems, organisationUnit, sheet );
+                    this.generatePeriodListing( reportInstance.getPeriodColumns(), exportItems, organisationUnit, sheet );
                 }
             }
         }
@@ -141,6 +140,10 @@
     // Supportive method
     // -------------------------------------------------------------------------
 
+    
+    /**
+     * NORMAL
+     * */
     private void generateNormal( Collection<ExportItem> exportItems, OrganisationUnit organisationUnit, Sheet sheet )
     {
         for ( ExportItem reportItem : exportItems )
@@ -175,6 +178,9 @@
         }
     }
 
+    /**
+     * ATTRIBUTE
+     * */
     private void generateAttribute( DataElementCategoryOptionCombo optionCombo, ExportReportAttribute exportReport,
         Collection<ExportItem> exportItems, OrganisationUnit organisationUnit, Sheet sheet )
     {
@@ -252,6 +258,9 @@
         }
     }
 
+    /**
+     * CATEGORY
+     * */
     private void generateVerticalOutPutFile( ExportReportCategory exportReport, Collection<ExportItem> exportItems,
         OrganisationUnit organisationUnit, Sheet sheet )
     {
@@ -386,13 +395,18 @@
         return true;
     }
 
+    /**
+     * CATEGORY-VERTICAL
+     * */
     private void generateCategoryVertical( ExportReportVerticalCategory exportReport,
-        Collection<ExportItem> exportItems, OrganisationUnit organisationUnit, Sheet sheet )
+        Collection<ExportItem> exportReportItems, OrganisationUnit organisationUnit, Sheet sheet )
     {
         DataElement de = null;
         Set<DataElementCategoryOptionCombo> optionCombos = new HashSet<DataElementCategoryOptionCombo>();
+        Set<DataElementCategoryOption> associatedCategoryOptions = new HashSet<DataElementCategoryOption>(
+            categoryOptionAssociationService.getCategoryOptions( organisationUnit ) );
 
-        for ( ExportItem reportItem : exportItems )
+        for ( ExportItem reportItem : exportReportItems )
         {
             int run = 0;
             int rowBegin = reportItem.getRow();
@@ -421,61 +435,69 @@
 
                 for ( DataElementCategoryOption categoryOption : group.getCategoryOptions() )
                 {
-                    if ( reportItem.getItemType().equalsIgnoreCase( ExportItem.TYPE.DATAELEMENT_NAME ) )
-                    {
-                        ExcelUtils.writeValueByPOI( rowBegin, reportItem.getColumn(), categoryOption.getName(),
-                            ExcelUtils.TEXT, sheet, this.csText10Bold );
-                    }
-                    else if ( reportItem.getItemType().equalsIgnoreCase( ExportItem.TYPE.SERIAL ) )
-                    {
-                        ExcelUtils.writeValueByPOI( rowBegin, reportItem.getColumn(), String.valueOf( serial ),
-                            ExcelUtils.NUMBER, sheet, this.csTextSerial );
-                    }
-                    else if ( reportItem.getItemType().equalsIgnoreCase( ExportItem.TYPE.FORMULA_EXCEL ) )
-                    {
-                        ExcelUtils.writeFormulaByPOI( rowBegin, reportItem.getColumn(), ExcelUtils
-                            .generateExcelFormula( reportItem.getExpression(), run, run ), sheet, csFormula );
-                    }
-                    else
-                    {
-                        for ( DataElementCategoryOptionCombo optionCombo : optionCombos )
-                        {
-                            if ( optionCombo.getCategoryOptions().contains( categoryOption ) )
+                    if ( associatedCategoryOptions.contains( categoryOption ) )
+                    {
+                        if ( reportItem.getItemType().equalsIgnoreCase( ExportItem.TYPE.DATAELEMENT_NAME ) )
+                        {
+                            ExcelUtils.writeValueByPOI( rowBegin, reportItem.getColumn(), categoryOption.getName(),
+                                ExcelUtils.TEXT, sheet, this.csText10Bold );
+                        }
+                        else if ( reportItem.getItemType().equalsIgnoreCase( ExportItem.TYPE.SERIAL ) )
+                        {
+                            ExcelUtils.writeValueByPOI( rowBegin, reportItem.getColumn(), String.valueOf( serial ),
+                                ExcelUtils.NUMBER, sheet, this.csTextSerial );
+                        }
+                        else if ( reportItem.getItemType().equalsIgnoreCase( ExportItem.TYPE.FORMULA_EXCEL ) )
+                        {
+                            ExcelUtils.writeFormulaByPOI( rowBegin, reportItem.getColumn(), ExcelUtils
+                                .generateExcelFormula( reportItem.getExpression(), run, run ), sheet, csFormula );
+                        }
+                        else
+                        {
+                            for ( DataElementCategoryOptionCombo optionCombo : optionCombos )
                             {
-                                ExportItem newReportItem = new ExportItem();
-
-                                String expression = reportItem.getExpression();
-                                expression = expression.replace( "*", String.valueOf( optionCombo.getId() ) );
-
-                                newReportItem.setPeriodType( reportItem.getPeriodType() );
-                                newReportItem.setExpression( expression );
-
-                                double value = this.getDataValue( newReportItem, organisationUnit );
-
-                                ExcelUtils.writeValueByPOI( rowBegin, reportItem.getColumn(), String.valueOf( value ),
-                                    ExcelUtils.NUMBER, sheet, this.csNumber );
-
-                                break;
+                                if ( optionCombo.getCategoryOptions().contains( categoryOption ) )
+                                {
+                                    ExportItem newReportItem = new ExportItem();
+
+                                    String expression = reportItem.getExpression();
+                                    expression = expression.replace( "*", String.valueOf( optionCombo.getId() ) );
+
+                                    newReportItem.setPeriodType( reportItem.getPeriodType() );
+                                    newReportItem.setExpression( expression );
+
+                                    double value = this.getDataValue( newReportItem, organisationUnit );
+
+                                    ExcelUtils.writeValueByPOI( rowBegin, reportItem.getColumn(), String
+                                        .valueOf( value ), ExcelUtils.NUMBER, sheet, this.csNumber );
+
+                                    break;
+                                }
                             }
                         }
+
+                        rowBegin++;
+                        serial++;
+                        run++;
+
+                        if ( reportItem.getItemType().equalsIgnoreCase( ExportItem.TYPE.DATAELEMENT ) )
+                        {
+                            String columnName = ExcelUtils.convertColumnNumberToName( reportItem.getColumn() );
+                            String formula = "SUM(" + columnName + (beginChapter + 1) + ":" + columnName
+                                + (rowBegin - 1) + ")";
+
+                            ExcelUtils.writeFormulaByPOI( beginChapter, reportItem.getColumn(), formula, sheet,
+                                this.csFormula );
+                        }
                     }
-
-                    rowBegin++;
-                    serial++;
-                    run++;
-                }
-
-                if ( reportItem.getItemType().equalsIgnoreCase( ExportItem.TYPE.DATAELEMENT ) )
-                {
-                    String columnName = ExcelUtils.convertColumnNumberToName( reportItem.getColumn() );
-                    String formula = "SUM(" + columnName + (beginChapter + 1) + ":" + columnName + (rowBegin - 1) + ")";
-
-                    ExcelUtils.writeFormulaByPOI( beginChapter, reportItem.getColumn(), formula, sheet, this.csFormula );
                 }
             }
         }
     }
 
+    /**
+     * ORGUNIT-LISTING
+     * */
     private void generateOrgUnitListing( ExportReportOrganizationGroupListing exportReport,
         Map<OrganisationUnitGroup, OrganisationUnitLevel> orgUniGroupAtLevels, Collection<ExportItem> exportItems,
         OrganisationUnit organisationUnit, Sheet sheet )
@@ -613,6 +635,9 @@
         }
     }
 
+    /**
+     * PERIOD-LISTING
+     * */
     private void generatePeriodListing( Set<PeriodColumn> periodColumns, Collection<ExportItem> exportItems,
         OrganisationUnit organisationUnit, Sheet sheet )
     {

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportAttributeAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportAttributeAction.java	2012-05-03 10:04:29 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportAttributeAction.java	2012-05-04 09:50:39 +0000
@@ -86,7 +86,7 @@
     // Supportive method
     // -------------------------------------------------------------------------
 
-    public void generateOutPutFile( DataElementCategoryOptionCombo optionCombo, ExportReportAttribute exportReport,
+    private void generateOutPutFile( DataElementCategoryOptionCombo optionCombo, ExportReportAttribute exportReport,
         Collection<ExportItem> exportReportItems, OrganisationUnit organisationUnit, Sheet sheet )
     {
         boolean flag = false;

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportCategoryAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportCategoryAction.java	2012-05-03 10:04:29 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportCategoryAction.java	2012-05-04 09:50:39 +0000
@@ -80,7 +80,7 @@
     // Supportive method
     // -------------------------------------------------------------------------
 
-    public void generateVerticalOutPutFile( ExportReportCategory exportReport,
+    private void generateVerticalOutPutFile( ExportReportCategory exportReport,
         Collection<ExportItem> exportReportItems, OrganisationUnit organisationUnit, Sheet sheet )
     {
         for ( ExportItem reportItem : exportReportItems )
@@ -162,7 +162,7 @@
         }
     }
 
-    public void generateHorizontalOutPutFile( ExportReportCategory exportReport,
+    private void generateHorizontalOutPutFile( ExportReportCategory exportReport,
         Collection<ExportItem> exportReportItems, OrganisationUnit organisationUnit, Sheet sheet )
     {
         for ( ExportItem reportItem : exportReportItems )
@@ -197,7 +197,7 @@
         }
     }
 
-    public boolean isVerticalCategory( Collection<ExportItem> items )
+    private boolean isVerticalCategory( Collection<ExportItem> items )
     {
         Integer previousRow = null;
 

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportNormalAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportNormalAction.java	2012-05-03 10:04:29 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportNormalAction.java	2012-05-04 09:50:39 +0000
@@ -71,7 +71,7 @@
     // Supportive method
     // -------------------------------------------------------------------------
 
-    public void generateOutPutFile( Collection<ExportItem> exportReportItems, OrganisationUnit organisationUnit,
+    private void generateOutPutFile( Collection<ExportItem> exportReportItems, OrganisationUnit organisationUnit,
         Sheet sheet )
     {
         for ( ExportItem reportItem : exportReportItems )

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportOrgGroupListingAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportOrgGroupListingAction.java	2012-05-03 10:04:29 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportOrgGroupListingAction.java	2012-05-04 09:50:39 +0000
@@ -97,7 +97,7 @@
     // Supportive method
     // -------------------------------------------------------------------------
 
-    public void generateOutPutFile( ExportReportOrganizationGroupListing exportReport,
+    private void generateOutPutFile( ExportReportOrganizationGroupListing exportReport,
         Map<OrganisationUnitGroup, OrganisationUnitLevel> orgUniGroupAtLevels,
         Collection<ExportItem> exportReportItems, OrganisationUnit organisationUnit, Sheet sheet )
     {

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportPeriodColumnListingAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportPeriodColumnListingAction.java	2012-05-03 10:04:29 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportPeriodColumnListingAction.java	2012-05-04 09:50:39 +0000
@@ -74,7 +74,7 @@
     // Supportive method
     // -------------------------------------------------------------------------
 
-    public void generateOutPutFile( Set<PeriodColumn> periodColumns, Collection<ExportItem> exportReportItems,
+    private void generateOutPutFile( Set<PeriodColumn> periodColumns, Collection<ExportItem> exportReportItems,
         OrganisationUnit organisationUnit, Sheet sheet )
     {
         for ( ExportItem reportItem : exportReportItems )

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportVerticalCategoryAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportVerticalCategoryAction.java	2012-05-03 10:04:29 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/exporting/action/GenerateReportVerticalCategoryAction.java	2012-05-04 09:50:39 +0000
@@ -27,6 +27,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 import static org.hisp.dhis.dataelement.DataElementOperand.SEPARATOR;
+
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
@@ -37,12 +38,14 @@
 import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.period.Period;
+import org.hisp.dhis.reportsheet.CategoryOptionAssociationService;
 import org.hisp.dhis.reportsheet.CategoryOptionGroupOrder;
 import org.hisp.dhis.reportsheet.ExportItem;
 import org.hisp.dhis.reportsheet.ExportReport;
 import org.hisp.dhis.reportsheet.ExportReportVerticalCategory;
 import org.hisp.dhis.reportsheet.exporting.AbstractGenerateExcelReportSupport;
 import org.hisp.dhis.reportsheet.utils.ExcelUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * @author Dang Duy Hieu
@@ -51,6 +54,9 @@
 public class GenerateReportVerticalCategoryAction
     extends AbstractGenerateExcelReportSupport
 {
+    @Autowired
+    private CategoryOptionAssociationService categoryOptionAssociationService;
+
     @Override
     protected void executeGenerateOutputFile( ExportReport exportReport, Period period )
         throws Exception
@@ -75,11 +81,13 @@
     // Supportive method
     // -------------------------------------------------------------------------
 
-    public void generateVerticalOutPutFile( ExportReportVerticalCategory exportReport,
+    private void generateVerticalOutPutFile( ExportReportVerticalCategory exportReport,
         Collection<ExportItem> exportReportItems, OrganisationUnit organisationUnit, Sheet sheet )
     {
         DataElement de = null;
         Set<DataElementCategoryOptionCombo> optionCombos = new HashSet<DataElementCategoryOptionCombo>();
+        Set<DataElementCategoryOption> associatedCategoryOptions = new HashSet<DataElementCategoryOption>(
+            categoryOptionAssociationService.getCategoryOptions( organisationUnit ) );
 
         for ( ExportItem reportItem : exportReportItems )
         {
@@ -110,56 +118,61 @@
 
                 for ( DataElementCategoryOption categoryOption : group.getCategoryOptions() )
                 {
-                    if ( reportItem.getItemType().equalsIgnoreCase( ExportItem.TYPE.DATAELEMENT_NAME ) )
-                    {
-                        ExcelUtils.writeValueByPOI( rowBegin, reportItem.getColumn(), categoryOption.getName(),
-                            ExcelUtils.TEXT, sheet, this.csText10Bold );
-                    }
-                    else if ( reportItem.getItemType().equalsIgnoreCase( ExportItem.TYPE.SERIAL ) )
-                    {
-                        ExcelUtils.writeValueByPOI( rowBegin, reportItem.getColumn(), String.valueOf( serial ),
-                            ExcelUtils.NUMBER, sheet, this.csTextSerial );
-                    }
-                    else if ( reportItem.getItemType().equalsIgnoreCase( ExportItem.TYPE.FORMULA_EXCEL ) )
-                    {
-                        ExcelUtils.writeFormulaByPOI( rowBegin, reportItem.getColumn(), ExcelUtils
-                            .generateExcelFormula( reportItem.getExpression(), run, run ), sheet, csFormula );
-                    }
-                    else
-                    {
-                        for ( DataElementCategoryOptionCombo optionCombo : optionCombos )
-                        {
-                            if ( optionCombo.getCategoryOptions().contains( categoryOption ) )
+                    if ( associatedCategoryOptions.contains( categoryOption ) )
+                    {
+                        if ( reportItem.getItemType().equalsIgnoreCase( ExportItem.TYPE.DATAELEMENT_NAME ) )
+                        {
+                            ExcelUtils.writeValueByPOI( rowBegin, reportItem.getColumn(), categoryOption.getName(),
+                                ExcelUtils.TEXT, sheet, this.csText10Bold );
+                        }
+                        else if ( reportItem.getItemType().equalsIgnoreCase( ExportItem.TYPE.SERIAL ) )
+                        {
+                            ExcelUtils.writeValueByPOI( rowBegin, reportItem.getColumn(), String.valueOf( serial ),
+                                ExcelUtils.NUMBER, sheet, this.csTextSerial );
+                        }
+                        else if ( reportItem.getItemType().equalsIgnoreCase( ExportItem.TYPE.FORMULA_EXCEL ) )
+                        {
+                            ExcelUtils.writeFormulaByPOI( rowBegin, reportItem.getColumn(), ExcelUtils
+                                .generateExcelFormula( reportItem.getExpression(), run, run ), sheet, csFormula );
+                        }
+                        else
+                        {
+                            for ( DataElementCategoryOptionCombo optionCombo : optionCombos )
                             {
-                                ExportItem newReportItem = new ExportItem();
-
-                                String expression = reportItem.getExpression();
-                                expression = expression.replace( "*", String.valueOf( optionCombo.getId() ) );
-
-                                newReportItem.setPeriodType( reportItem.getPeriodType() );
-                                newReportItem.setExpression( expression );
-
-                                double value = this.getDataValue( newReportItem, organisationUnit );
-
-                                ExcelUtils.writeValueByPOI( rowBegin, reportItem.getColumn(), String.valueOf( value ),
-                                    ExcelUtils.NUMBER, sheet, this.csNumber );
-
-                                break;
+                                if ( optionCombo.getCategoryOptions().contains( categoryOption ) )
+                                {
+                                    ExportItem newReportItem = new ExportItem();
+
+                                    String expression = reportItem.getExpression();
+                                    expression = expression.replace( "*", String.valueOf( optionCombo.getId() ) );
+
+                                    newReportItem.setPeriodType( reportItem.getPeriodType() );
+                                    newReportItem.setExpression( expression );
+
+                                    double value = this.getDataValue( newReportItem, organisationUnit );
+
+                                    ExcelUtils.writeValueByPOI( rowBegin, reportItem.getColumn(), String
+                                        .valueOf( value ), ExcelUtils.NUMBER, sheet, this.csNumber );
+
+                                    break;
+                                }
                             }
                         }
+
+                        rowBegin++;
+                        serial++;
+                        run++;
+
+                        if ( reportItem.getItemType().equalsIgnoreCase( ExportItem.TYPE.DATAELEMENT ) )
+                        {
+                            String columnName = ExcelUtils.convertColumnNumberToName( reportItem.getColumn() );
+                            String formula = "SUM(" + columnName + (beginChapter + 1) + ":" + columnName
+                                + (rowBegin - 1) + ")";
+
+                            ExcelUtils.writeFormulaByPOI( beginChapter, reportItem.getColumn(), formula, sheet,
+                                this.csFormula );
+                        }
                     }
-
-                    rowBegin++;
-                    serial++;
-                    run++;
-                }
-
-                if ( reportItem.getItemType().equalsIgnoreCase( ExportItem.TYPE.DATAELEMENT ) )
-                {
-                    String columnName = ExcelUtils.convertColumnNumberToName( reportItem.getColumn() );
-                    String formula = "SUM(" + columnName + (beginChapter + 1) + ":" + columnName + (rowBegin - 1) + ")";
-
-                    ExcelUtils.writeFormulaByPOI( beginChapter, reportItem.getColumn(), formula, sheet, this.csFormula );
                 }
             }
         }

=== 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-05-03 10:04:29 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/resources/META-INF/dhis/beans.xml	2012-05-04 09:50:39 +0000
@@ -300,6 +300,21 @@
 		id="org.hisp.dhis.reportsheet.cogroup.action.GetCategoryOptionsByCategoryAction"
 		class="org.hisp.dhis.reportsheet.cogroup.action.GetCategoryOptionsByCategoryAction"
 		scope="prototype" />
+	
+	<bean
+		id="org.hisp.dhis.reportsheet.cogroup.action.OpenCategoryOptionAssociationsAction"
+		class="org.hisp.dhis.reportsheet.cogroup.action.OpenCategoryOptionAssociationsAction"
+		scope="prototype" />
+	
+	<bean
+		id="org.hisp.dhis.reportsheet.cogroup.action.ShowDefineCategoryOptionAssociationsAction"
+		class="org.hisp.dhis.reportsheet.cogroup.action.ShowDefineCategoryOptionAssociationsAction"
+		scope="prototype" />
+	
+	<bean
+		id="org.hisp.dhis.reportsheet.cogroup.action.UpdateCategoryOptionAssociationsAction"
+		class="org.hisp.dhis.reportsheet.cogroup.action.UpdateCategoryOptionAssociationsAction"
+		scope="prototype" />
 
 	<!-- REPORT EXCEL ATTRIBUTE BEAN -->
 

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/i18n_module.properties'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/i18n_module.properties	2012-05-03 10:04:29 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/i18n_module.properties	2012-05-04 09:50:39 +0000
@@ -324,9 +324,15 @@
 no_attribute_selected		= There is no attribute selected
 selected_list_should_not_empty = The selected list should not empty
 select_category				= Select category
+select_category_option		= Select category option
 please_select_category		= Please select a category
+please_select_category_option = Please select category option
 categoryoption_groups		= Category Option Groups
 specify_export_report		= Please select report
 export_type					= Export type
 export_single				= Export a single report
-export_multi				= Export multi-reports
\ No newline at end of file
+export_multi				= Export multi-reports
+categoryoption_associations = Open category option associations
+define_categoryoption_associations = Define Categoryoption Associations Management
+update_associations_successful = Update associations successfully
+category_options			= Category options
\ No newline at end of file

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/i18n_module_vi_VN.properties'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/i18n_module_vi_VN.properties	2012-05-03 10:04:29 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/resources/org/hisp/dhis/reportsheet/i18n_module_vi_VN.properties	2012-05-04 09:50:39 +0000
@@ -359,9 +359,15 @@
 no_attribute_selected = Kh\u00f4ng c\u00f3 Thu\u1ed9c t\u00ednh n\u00e0o \u0111\u01b0\u1ee3c ch\u1ecdn trong khi thi\u1ebft k\u1ebf b\u00e1o c\u00e1o
 attribute_with_id = Thu\u1ed9c t\u00ednh c\u00f3 m\u00e3
 select_category	= Ch\u1ecdn ph\u00e2n lo\u1ea1i
+select_category_option = Select ph\u1ea7n t\u1eed ph\u00e2n lo\u1ea1i
 please_select_category = H\u00e3y ch\u1ecdn ph\u00e2n lo\u1ea1i
+please_select_category_option = H\u00e3y ch\u1ecdn ph\u1ea7n t\u1eed ph\u00e2n lo\u1ea1i
 categoryoption_groups = Nh\u00f3m c\u00e1c Ph\u00e2n lo\u1ea1i
 specify_export_report = H\u00e3y ch\u1ecdn b\u00e1o c\u00e1o
 export_type	= Ki\u1ec3u xu\u1ea5t b\u00e1o c\u00e1o
 export_single = Xu\u1ea5t b\u00e1o c\u00e1o \u0111\u01a1n l\u1ebb
-export_multi = Xu\u1ea5t \u0111a b\u00e1o c\u00e1o
\ No newline at end of file
+export_multi = Xu\u1ea5t \u0111a b\u00e1o c\u00e1o
+categoryoption_associations = G\u00e1n ph\u1ea7n t\u1eed ph\u00e2n lo\u1ea1i cho \u0111\u01a1n v\u1ecb
+define_categoryoption_associations = Qu\u1ea3n l\u00fd g\u00e1n ph\u1ea7n t\u1eed ph\u00e2n lo\u1ea1i cho \u0111\u01a1n v\u1ecb
+update_associations_successful = C\u1eadp nh\u1eadt th\u00e0nh c\u00f4ng
+category_options = Ph\u1ea7n t\u1eed ph\u00e2n lo\u1ea1i
\ No newline at end of file

=== 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-05-03 10:04:29 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/resources/struts.xml	2012-05-04 09:50:39 +0000
@@ -287,6 +287,26 @@
 				/dhis-web-spreadsheet-reporting/jsonCategoryOptions.vm</result>
 			<param name="onExceptionReturn">plainTextError</param>
 		</action>
+		
+		<action name="openCategoryOptionAssociations"
+			class="org.hisp.dhis.reportsheet.cogroup.action.OpenCategoryOptionAssociationsAction">
+			<result name="success" type="velocity">/main.vm</result>
+			<param name="page">/dhis-web-spreadsheet-reporting/categoryOptionAssociations.vm</param>
+			<param name="menu">/dhis-web-spreadsheet-reporting/menu.vm</param>
+			<param name="stylesheets">style/basic.css</param>
+		</action>
+
+		<action name="showAssociationsByCategoryOption"
+			class="org.hisp.dhis.reportsheet.cogroup.action.ShowDefineCategoryOptionAssociationsAction">
+			<result name="success" type="velocity-json">
+				/dhis-web-commons/ajax/jsonResponseSuccess.vm</result>
+		</action>
+
+		<action name="updateCategoryOptionAssociations"
+			class="org.hisp.dhis.reportsheet.cogroup.action.UpdateCategoryOptionAssociationsAction">
+			<result name="success" type="velocity-json">
+				/dhis-web-commons/ajax/jsonResponseSuccess.vm</result>
+		</action>
 
 		<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
 		<!-- DATAELEMENT GROUP ORDER FOR CATEGORY ACTION 				   -->

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/categoryOptionAssociations.vm'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/categoryOptionAssociations.vm	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/categoryOptionAssociations.vm	2012-05-04 09:50:39 +0000
@@ -0,0 +1,91 @@
+<script type="text/javascript">
+	var validator = null;
+
+	jQuery(document).ready( function()
+	{
+		validator = validation( "categoryOptionAssociationsForm", function( form ) { validateCategoryOptionAssociations( form ); });
+	} );
+	
+	var i18n_verify_category_option = '$encoder.jsEscape($i18n.getString( 'please_select_category_option' ) , "'")';
+</script>
+
+<h3>$i18n.getString( "define_categoryoption_associations" )</h3>
+
+<h4>$encoder.htmlEncode( $!group.name )</h4>
+
+<form id="categoryOptionAssociationsForm" action="updateCategoryOptionAssociations.action">  
+	<table>
+		<tbody>
+			<tr><th>$i18n.getString( "category_options" )</th></tr>
+			<tr>
+				<td>
+					<select id="categoryOptionId" style="width:220px" onchange="getAssociationsByCategoryOption( this.value )" class="{validate:{required:true}}">
+						<option value="">[ $i18n.getString( "select_category_option" ) ]</option>
+						#foreach( $option in $!group.categoryOptions )
+						<option value="$!option.id">$encoder.htmlEncode( $!option.name )</option>
+						#end
+					</select>
+				</td>
+			</tr>
+		</tbody>
+	</table>
+  
+  <table id="selectionTable">
+	<tr>
+	  <td>
+		#organisationUnitSelectionTree( true, true, false )
+	  </td>
+    </tr>
+    <tr>
+      <td>
+        <input type="submit" id="submitButton" value="$i18n.getString( 'save' )" style="width:10em"/>
+		<input type="button" onclick="window.location.href='listCategoryOptionGroupOrderForExportReport.action?id=$!reportId'" value="$i18n.getString( 'back' )" style="width:10em"/>
+      </td>
+    </tr>
+  </table>
+
+</form>
+
+<script type="text/javascript">
+
+	function getAssociationsByCategoryOption( value )
+	{
+		if ( value && value != "" )
+		{
+			jQuery.get( "showAssociationsByCategoryOption.action",
+			{
+				categoryOptionId: value
+			}, function( json )
+			{
+				if ( json.response == "success" ) {
+					selectionTree.buildSelectionTree();
+				}
+			} );
+		} else {
+			selectionTree.clearSelectedOrganisationUnits();
+			selectionTree.buildSelectionTree();
+		}
+	}
+	
+	function validateCategoryOptionAssociations( _form )
+	{
+		var categoryOptionId = getFieldValue( "categoryOptionId" );
+	
+		if ( categoryOptionId && categoryOptionId == "" )
+		{
+			markInvalid( "categoryOptionId", i18n_verify_category_option );
+			return;
+		}
+	
+		jQuery.get( _form.action,
+		{
+			categoryOptionId: categoryOptionId
+		}, function ( json ) {
+			if ( json.response == "success" ) {
+				showSuccessMessage( json.message );
+			} else {
+				showErrorMessage( json.message );
+			}
+		} );
+	}
+</script>
\ No newline at end of file

=== modified 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	2012-04-29 09:57:26 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/categoryOptionGroupOrder.js	2012-05-04 09:50:39 +0000
@@ -140,4 +140,12 @@
 	moveAllById( 'availableList', 'selectedList' );
 	selectAllById( 'selectedList' );
 	document.forms[0].submit();
+}
+
+/*
+ * Open Category Option Associations
+ */
+function openCategoryOptionAssociations( id )
+{
+	window.location = "openCategoryOptionAssociations.action?id="+id+"&reportId="+reportId;
 }
\ No newline at end of file

=== modified 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	2012-04-29 09:57:26 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/listCategoryOptionGroupOrder.vm	2012-05-04 09:50:39 +0000
@@ -52,9 +52,10 @@
 			<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:openCategoryOptionAssociations( '$group.id' );" title="$i18n.getString( 'categoryoption_associations' )"><img src="../images/assign.png" border="1px" alt="$i18n.getString( 'categoryoption_associations' )"/></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:deleteCategoryOptionGroupOrder( '$group.id', '$group.name' );" title="$i18n.getString( 'remove' )"><img src="../images/delete.png" alt="$i18n.getString( 'remove' )"/></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>