← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 9428: local vn - Added new simple GUI for adding/editing department directly.

 

------------------------------------------------------------
revno: 9428
committer: Hieu <hieu.hispvietnam@xxxxxxxxx>
branch nick: dhis2
timestamp: Thu 2013-01-03 17:00:51 +0700
message:
  local vn - Added new simple GUI for adding/editing department directly.
added:
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/organisationunit/action/AddDepartmentAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/organisationunit/action/ShowAddDepartmentFormAction.java
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/department.vm
  local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/department.js
modified:
  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/menu.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-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/organisationunit/action/AddDepartmentAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/organisationunit/action/AddDepartmentAction.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/organisationunit/action/AddDepartmentAction.java	2013-01-03 10:00:51 +0000
@@ -0,0 +1,175 @@
+package org.hisp.dhis.reportsheet.organisationunit.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.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+
+import org.hisp.dhis.i18n.I18nFormat;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.organisationunit.OrganisationUnitGroup;
+import org.hisp.dhis.organisationunit.OrganisationUnitGroupService;
+import org.hisp.dhis.organisationunit.OrganisationUnitService;
+import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager;
+
+import com.opensymphony.xwork2.Action;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public class AddDepartmentAction
+    implements Action
+{
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    private I18nFormat format;
+
+    public void setFormat( I18nFormat format )
+    {
+        this.format = format;
+    }
+
+    private OrganisationUnitService organisationUnitService;
+
+    public void setOrganisationUnitService( OrganisationUnitService organisationUnitService )
+    {
+        this.organisationUnitService = organisationUnitService;
+    }
+
+    private OrganisationUnitGroupService organisationUnitGroupService;
+
+    public void setOrganisationUnitGroupService( OrganisationUnitGroupService organisationUnitGroupService )
+    {
+        this.organisationUnitGroupService = organisationUnitGroupService;
+    }
+
+    private OrganisationUnitSelectionManager selectionManager;
+
+    public void setSelectionManager( OrganisationUnitSelectionManager selectionManager )
+    {
+        this.selectionManager = selectionManager;
+    }
+
+    // -------------------------------------------------------------------------
+    // Input & Output
+    // -------------------------------------------------------------------------
+
+    private String name;
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+    private String shortName;
+
+    public void setShortName( String shortName )
+    {
+        this.shortName = shortName;
+    }
+
+    private Collection<String> selectedGroups = new HashSet<String>();
+
+    public void setSelectedGroups( Collection<String> selectedGroups )
+    {
+        this.selectedGroups = selectedGroups;
+    }
+
+    private Integer organisationUnitId;
+
+    public Integer getOrganisationUnitId()
+    {
+        return organisationUnitId;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    public String execute()
+        throws Exception
+    {
+        Date date = format.parseDateTime( Calendar.getInstance().getTime().toString() );
+
+        // ---------------------------------------------------------------------
+        // Get parent
+        // ---------------------------------------------------------------------
+
+        OrganisationUnit parent = selectionManager.getSelectedOrganisationUnit();
+
+        if ( parent == null )
+        {
+            // -----------------------------------------------------------------
+            // If no unit is selected, the parent is the parent of the roots
+            // -----------------------------------------------------------------
+
+            parent = selectionManager.getRootOrganisationUnitsParent();
+        }
+
+        // ---------------------------------------------------------------------
+        // Create organization unit
+        // ---------------------------------------------------------------------
+
+        OrganisationUnit organisationUnit = new OrganisationUnit( name, shortName, null, date, null, true, null );
+
+        organisationUnit.setParent( parent );
+
+        if ( parent != null )
+        {
+            parent.getChildren().add( organisationUnit );
+        }
+
+        // ---------------------------------------------------------------------
+        // Must persist org-unit before adding data sets because association are
+        // updated on both sides (and this side is inverse)
+        // ---------------------------------------------------------------------
+
+        organisationUnitId = organisationUnitService.addOrganisationUnit( organisationUnit );
+
+        for ( String id : selectedGroups )
+        {
+            OrganisationUnitGroup group = organisationUnitGroupService
+                .getOrganisationUnitGroup( Integer.parseInt( id ) );
+
+            if ( group != null )
+            {
+                group.addOrganisationUnit( organisationUnit );
+                organisationUnitGroupService.updateOrganisationUnitGroup( group );
+            }
+        }
+
+        organisationUnitService.updateOrganisationUnit( organisationUnit );
+
+        return SUCCESS;
+    }
+}

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/organisationunit/action/ShowAddDepartmentFormAction.java'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/organisationunit/action/ShowAddDepartmentFormAction.java	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/java/org/hisp/dhis/reportsheet/organisationunit/action/ShowAddDepartmentFormAction.java	2013-01-03 10:00:51 +0000
@@ -0,0 +1,146 @@
+package org.hisp.dhis.reportsheet.organisationunit.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 static org.apache.commons.lang.StringUtils.isNotBlank;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.organisationunit.OrganisationUnitGroupService;
+import org.hisp.dhis.organisationunit.OrganisationUnitGroupSet;
+import org.hisp.dhis.organisationunit.OrganisationUnitService;
+import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager;
+import org.hisp.dhis.paging.ActionPagingSupport;
+
+/**
+ * @author Dang Duy Hieu
+ * @version $Id$
+ */
+public class ShowAddDepartmentFormAction
+    extends ActionPagingSupport<OrganisationUnit>
+{
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    private OrganisationUnitService organisationUnitService;
+
+    public void setOrganisationUnitService( OrganisationUnitService organisationUnitService )
+    {
+        this.organisationUnitService = organisationUnitService;
+    }
+
+    private OrganisationUnitGroupService organisationUnitGroupService;
+
+    public void setOrganisationUnitGroupService( OrganisationUnitGroupService organisationUnitGroupService )
+    {
+        this.organisationUnitGroupService = organisationUnitGroupService;
+    }
+
+    private OrganisationUnitSelectionManager selectionManager;
+
+    public void setSelectionManager( OrganisationUnitSelectionManager selectionManager )
+    {
+        this.selectionManager = selectionManager;
+    }
+
+    // -------------------------------------------------------------------------
+    // Input & Output
+    // -------------------------------------------------------------------------
+
+    private List<OrganisationUnitGroupSet> groupSets;
+
+    public List<OrganisationUnitGroupSet> getGroupSets()
+    {
+        return groupSets;
+    }
+
+    private List<OrganisationUnit> organisationUnits = new ArrayList<OrganisationUnit>();
+
+    public List<OrganisationUnit> getOrganisationUnits()
+    {
+        return organisationUnits;
+    }
+
+    private String key;
+
+    public String getKey()
+    {
+        return key;
+    }
+
+    public void setKey( String key )
+    {
+        this.key = key;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    public String execute()
+    {
+        groupSets = new ArrayList<OrganisationUnitGroupSet>( organisationUnitGroupService
+            .getCompulsoryOrganisationUnitGroupSetsWithMembers() );
+
+        Collections.sort( groupSets, IdentifiableObjectNameComparator.INSTANCE );
+
+        //
+        
+        Collection<OrganisationUnit> selectedUnits = selectionManager.getSelectedOrganisationUnits();
+
+        if ( selectedUnits.isEmpty() )
+        {
+            organisationUnits.addAll( selectionManager.getRootOrganisationUnits() );
+        }
+        else
+        {
+            for ( OrganisationUnit selectedUnit : selectedUnits )
+            {
+                organisationUnits.addAll( selectedUnit.getChildren() );
+            }
+        }
+
+        Collections.sort( organisationUnits, new IdentifiableObjectNameComparator() );
+
+        if ( isNotBlank( key ) )
+        {
+            organisationUnitService.searchOrganisationUnitByName( organisationUnits, key );
+        }
+
+        this.paging = createPaging( organisationUnits.size() );
+        organisationUnits = getBlockElement( organisationUnits, paging.getStartPos(), paging.getPageSize() );
+
+        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-12-17 10:36:42 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/resources/META-INF/dhis/beans.xml	2013-01-03 10:00:51 +0000
@@ -1538,4 +1538,34 @@
 		scope="prototype">
 	</bean>
 	
+	<!-- OrganisationUnit -->
+	
+	<bean id="org.hisp.dhis.reportsheet.organisationunit.ShowAddDepartmentFormAction"
+		class="org.hisp.dhis.reportsheet.organisationunit.ShowAddDepartmentFormAction"
+		scope="prototype">
+		<property name="organisationUnitService">
+		  <ref bean="org.hisp.dhis.organisationunit.OrganisationUnitService" />
+		</property>
+		<property name="organisationUnitGroupService">
+		  <ref bean="org.hisp.dhis.organisationunit.OrganisationUnitGroupService" />
+		</property>
+		<property name="selectionManager">
+		  <ref bean="org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager" />
+		</property>
+	</bean>
+  
+	<bean id="org.hisp.dhis.reportsheet.organisationunit.AddDepartmentAction"
+		class="org.hisp.dhis.reportsheet.organisationunit.AddDepartmentAction"
+		scope="prototype">
+		<property name="organisationUnitService">
+		  <ref bean="org.hisp.dhis.organisationunit.OrganisationUnitService" />
+		</property>
+		<property name="organisationUnitGroupService">
+		  <ref bean="org.hisp.dhis.organisationunit.OrganisationUnitGroupService" />
+		</property>
+		<property name="selectionManager">
+		  <ref bean="org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager" />
+		</property>
+	</bean>
+	
 </beans>

=== 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-12-18 08:08:53 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/resources/struts.xml	2013-01-03 10:00:51 +0000
@@ -1872,6 +1872,20 @@
 			<result name="error" type="velocity-json">../dhis-web-commons/ajax/jsonResponseError.vm</result>
 			<param name="onExceptionReturn">plainTextError</param>
 		</action>
-		
+
+		<!-- OrganisationUnit -->
+
+		<action name="department" class="org.hisp.dhis.reportsheet.organisationunit.ShowAddDepartmentFormAction">
+		  <result name="success" type="velocity">/main.vm</result>
+		  <param name="page">/dhis-web-maintenance-organisationunit/department.vm</param>
+		  <param name="menu">/dhis-web-maintenance-organisationunit/menuWithTree.vm</param>
+		  <param name="javascripts">../dhis-web-commons/ouwt/ouwt.js,javascript/department.js</param>
+		  <interceptor-ref name="organisationUnitTreeStack" />
+		</action>
+
+		<action name="addDepartment" class="org.hisp.dhis.reportsheet.organisationunit.AddDepartmentAction">
+		  <result name="success" type="redirect">department.action</result>
+		  <param name="requiredAuthorities">F_ORGANISATIONUNIT_ADD</param>
+		</action>
 	</package>
 </struts>
\ No newline at end of file

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/department.vm'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/department.vm	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/department.vm	2013-01-03 10:00:51 +0000
@@ -0,0 +1,198 @@
+<script type="text/javascript">
+	jQuery(document).ready(function(){
+
+		validation('addDepartmentForm', function(form) {
+			form.submit();
+		});
+		
+		tableSorter( 'listTable' );
+		jQuery("#name").focus();
+		jQuery( "table.listTable tbody tr td[allowRename=true]" ).bind( "click", showRename );
+	});
+
+	function showRename( event )
+	{
+		var jqsource = jQuery( "#" + this.id );
+		var name = jqsource.html();
+		_input = "<input type='text' style='width:" + name.length + "em'";
+		_input += " onkeypress='renameByEnter( event, " + '"' + this.id + '"' + ', "' + name + '"' + ", this.value )'";
+		_input += " onblur='renameByBlur( " + '"' + this.id + '"' + ', "' + name + '"' + ", this.value )'/>";
+
+		jqsource.html( _input );
+		jqsource.unbind( "click" );
+		jqsource.find( "input" ).focus();
+		jqsource.find( "input" ).val( name );
+	}
+	
+	function renameByEnter( event, id, _old, _new )
+	{
+		var key = event.keyCode || event.charCode || event.which;
+	
+		if ( key == 13 || key == 1 ) // Enter
+		{
+			var jqsource = jQuery( "#" + id );
+			jqsource.bind( "click", showRename );
+
+			if ( _old != _new )
+			{
+				jQuery.postUTF8( "renameOrganisationUnit.action",
+				{
+					id: id.substring(2, id.length),
+					name: _new
+				}, function( json )
+				{
+					if ( json.response == "success" )
+					{
+						jqsource.html( _new );
+					} else {
+						jqsource.html( _old );
+						showWarningMessage( json.message );
+					}
+				} );
+			}
+			else { jqsource.html( _old ); }
+		}
+	}
+	
+	function renameByBlur( id, _old, _new )
+	{
+		var jqsource = jQuery( "#" + id );
+		jqsource.bind( "click", showRename );
+		jqsource.html( _old );	
+	}
+	
+	var previousName = '';
+	var adding_the_org_unit_failed = '$encoder.jsEscape( $i18n.getString( "adding_the_org_unit_failed" ) , "'" )';
+	var none = '$encoder.jsEscape( $i18n.getString( "none" ) , "'" )';
+	var yes = '$encoder.jsEscape( $i18n.getString( "yes" ) , "'" )';
+	var no = '$encoder.jsEscape( $i18n.getString( "no" ) , "'" )';
+	var confirm_to_delete_org_unit = '$encoder.jsEscape( $i18n.getString( "confirm_to_delete_org_unit" ) , "'" )';
+</script>
+
+<h3>$i18n.getString( "org_unit_management" ) #openHelp( "orgunit" )</h3>
+
+<form id="addDepartmentForm" name="addDepartmentForm" action="addDepartment.action" method="post">
+
+<table>
+    <tr>
+		<th colspan="2">$i18n.getString( "details" )</th>
+    </tr>
+	<tr>
+		<td style="width:200px"><label for="name">$i18n.getString( "name" ) <em title="$i18n.getString( 'required' )" class="required">*</em></label></td>
+		<td><input type="text" id="name" name="name" onchange="nameChanged()" style="width:20em" class="{validate:{required:true}}"/></td>
+	</tr>
+	<tr>
+		<td><label for="shortName">$i18n.getString( "short_name" ) <em title="$i18n.getString( 'required' )" class="required">*</em></label></td>
+		<td><input type="text" id="shortName" name="shortName" style="width:20em" class="{validate:{required:true}}"/></td>
+	</tr>
+</table>
+
+<table>
+    <tr>
+		<th colspan="2">$i18n.getString( "organisation_unit_groups" )</th>
+    </tr>
+	#foreach ( $groupSet in $groupSets )
+    <tr>
+		<td style="width:200px">$encoder.htmlEncode( $groupSet.name )</td>			
+		<td>
+			<select id="selectedGroups" name="selectedGroups" style="min-width: 244px;">
+				<option value="-1">[ $i18n.getString( "select_group" ) ]</option>
+				#foreach ( $group in $groupSet.getSortedGroups() )
+				<option value="$group.id">$group.name</option>
+				#end
+			</select>
+		</td>
+		<td>
+			<input type="submit" name="save" value="$i18n.getString( 'add' )" style="width: 10em;" />
+		</td>
+    </tr>
+	#end
+</table>
+
+</form>
+
+<br/>
+
+<h3>$i18n.getString( "list_of_organisation_unit" )</h3>
+
+<table class="mainPageTable">
+	<tr>
+		<td style="vertical-align:top">
+			<table width="100%">
+				<tr>
+					<td>#filterDiv( "organisationUnit" )</td>
+					<td colspan="3" style="text-align:right">
+						<input type="button" value="$i18n.getString( 'get_pdf' )" onclick="exportPDF( 'organisationUnit' );" style="width:80px"/>
+					</td>
+				</tr>
+			</table>
+			<table class="listTable" id="listTable">
+				<col/>
+				<col width="100px"/>
+				<col width="200px"/>			
+                <thead>				
+				<tr>
+					<th>$i18n.getString( "name" )</th>
+					<th class="{sorter: false}">$i18n.getString( "organisation_unit_groups" )</th>
+					<th class="{sorter: false}">$i18n.getString( "operations" )</th>
+				</tr>
+                </thead>
+				<tbody id="list">
+				#foreach( $organisationUnit in $organisationUnits )
+				<tr id="tr${organisationUnit.id}">
+					<td id="td${organisationUnit.id}" allowRename="true">$encoder.htmlEncode( $organisationUnit.name )</td>
+					<td>
+						<select style="width:190px">
+							#foreach( $group in $organisationUnit.groups )
+							<option>$group.name</option>
+							#end
+						</select>
+					</td>
+					<td style="text-align:right">
+						<a href="showUpdateOrganisationUnitForm.action?id=$organisationUnit.id" title="$i18n.getString( 'edit' )"><img src="../images/edit.png" alt="$i18n.getString( 'edit' )"/></a>
+						#if( $organisationUnit.children.size() == 0 && $auth.hasAccess( "dhis-web-maintenance-organisationunit", "removeOrganisationUnit" ) )
+						<a href="javascript:removeOrganisationUnit( $organisationUnit.id, '$encoder.jsEncode( $organisationUnit.name )' )" title="$i18n.getString( 'remove' )"><img src="../images/delete.png" alt="$i18n.getString( 'remove' )"/></a>
+						#else <img src="../images/delete-denied.png" alt="$i18n.getString( 'remove' )"/> #end
+						<a href="javascript:showOrganisationUnitDetails( $organisationUnit.id )" title="$i18n.getString( 'show_details' )"><img src="../images/information.png" alt="$i18n.getString( 'show_details' )"/></a>
+					</td>
+				</tr>
+				#end
+                </tbody>
+				#if ( $organisationUnits.size() == 0 )
+				<tr>
+					<td colspan="4">$i18n.getString( "this_org_unit_has_no_children" )</td>
+				</tr>
+				#end
+			</table>
+			<p></p>
+			#parse( "/dhis-web-commons/paging/paging.vm" )
+
+		</td>
+		<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( "short_name" ):</label><br/><span id="shortNameField"></span></p>
+				<p><label>$i18n.getString( "description" ):</label><br/><span id="descriptionField"></span></p>
+				<p><label>$i18n.getString( "code" ):</label><br/><span id="codeField"></span></p>
+				<p><label>$i18n.getString( "opening_date" ):</label><br/><span id="openingDateField"></span></p>
+				<p><label>$i18n.getString( "closed_date" ):</label><br/><span id="closedDateField"></span></p>
+				<p><label>$i18n.getString( "registers_date" ):</label><br/><span id="activeField"></span></p>
+				<p><label>$i18n.getString( "comment" ):</label><br/><span id="commentField"></span></p>
+                <p><label>$i18n.getString( "url" ):</label><br/><span id="urlField"></span></p>
+                <p><label>$i18n.getString( "last_updated" ):</label><br/><span id="lastUpdatedField"></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>

=== added file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/department.js'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/department.js	1970-01-01 00:00:00 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/javascript/department.js	2013-01-03 10:00:51 +0000
@@ -0,0 +1,70 @@
+// -----------------------------------------------------------------------------
+// Organisation unit selection listener
+// -----------------------------------------------------------------------------
+
+$( document ).ready( function()
+{
+    selection.setAutoSelectRoot( false );
+    selection.setRootUnselectAllowed( true );
+    selection.setListenerFunction( organisationUnitSelected, true );
+} );
+
+function organisationUnitSelected( orgUnitIds )
+{
+    window.location.href = 'department.action';
+}
+
+// -----------------------------------------------------------------------------
+// Export to PDF
+// -----------------------------------------------------------------------------
+
+function exportPDF( type )
+{
+	var params = "type=" + type;
+	
+	exportPdfByType( type, params );
+}
+
+// -----------------------------------------------------------------------------
+// View details
+// -----------------------------------------------------------------------------
+
+function showOrganisationUnitDetails( unitId )
+{
+    jQuery.post( '../dhis-web-commons-ajax-json/getOrganisationUnit.action',
+		{ id: unitId }, function ( json ) {
+		setInnerHTML( 'nameField', json.organisationUnit.name );
+		setInnerHTML( 'shortNameField', json.organisationUnit.shortName );
+		setInnerHTML( 'descriptionField', json.organisationUnit.description );
+		setInnerHTML( 'openingDateField', json.organisationUnit.openingDate );
+
+		var orgUnitCode = json.organisationUnit.code;
+		setInnerHTML( 'codeField', orgUnitCode ? orgUnitCode : '[' + none + ']' );
+
+		var closedDate = json.organisationUnit.closedDate;
+		setInnerHTML( 'closedDateField', closedDate ? closedDate : '[' + none + ']' );
+
+		var commentValue = json.organisationUnit.comment;
+		setInnerHTML( 'commentField', commentValue ? commentValue.replace( /\n/g, '<br>' ) : '[' + none + ']' );
+
+		var active = json.organisationUnit.active;
+		setInnerHTML( 'activeField', active == 'true' ? yes : no );
+
+		var url = json.organisationUnit.url;
+		setInnerHTML( 'urlField', url ? '<a href="' + url + '">' + url + '</a>' : '[' + none + ']' );
+
+		var lastUpdated = json.organisationUnit.lastUpdated;
+		setInnerHTML( 'lastUpdatedField', lastUpdated ? lastUpdated : '[' + none + ']' );
+
+		showDetails();
+	});
+}
+
+// -----------------------------------------------------------------------------
+// Remove organisation unit
+// -----------------------------------------------------------------------------
+
+function removeOrganisationUnit( unitId, unitName )
+{
+    removeItem( unitId, unitName, confirm_to_delete_org_unit, 'removeOrganisationUnit.action', subtree.refreshTree );
+}

=== modified file 'local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/menu.vm'
--- local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/menu.vm	2012-12-13 08:59:31 +0000
+++ local/vn/dhis-web-spreadsheet-reporting/src/main/webapp/dhis-web-spreadsheet-reporting/menu.vm	2013-01-03 10:00:51 +0000
@@ -5,6 +5,11 @@
 
 <h2><a href="selectExportReportParam.action">$i18n.getString( "generate_report" )&nbsp;</a></h2>
 <ul>
+	<li><a href="department.action">$i18n.getString( "organisationunit" )</a></li>
+</ul>
+
+<h2><a href="selectExportReportParam.action">$i18n.getString( "generate_report" )&nbsp;</a></h2>
+<ul>
 	<li><a href="../dhis-web-reporting/displayViewDataCompletenessForm.action">$i18n.getString( "view_data_status" )</a></li>
 	<li><a href="selectExportReportParam.action">$i18n.getString( "generate_report" )&nbsp;</a></li>
 	<!--