← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 2047: Add groupBy field to PatientAttribute to check if this attribute is used to group the beneficiary

 

------------------------------------------------------------
revno: 2047
committer: Tran Ng Minh Luan <Luan@MinhLuan-PC>
branch nick: dhis2
timestamp: Fri 2010-11-12 17:28:30 +0700
message:
  Add groupBy field to PatientAttribute to check if this attribute is used to group the beneficiary
  Send PatientAttribute (groupBy = true) to mobile to group beneficiary (Village Grouping blueprint)
added:
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/web/api/model/PatientAttribute.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientAttribute.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientAttributeService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientAttributeStore.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java
  dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/DefaultPatientAttributeService.java
  dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/hibernate/HibernatePatientAttributeStore.java
  dhis-2/dhis-services/dhis-service-patient/src/main/resources/org/hisp/dhis/patient/hibernate/PatientAttribute.hbm.xml
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/web/api/model/ActivityPlan.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/web/api/model/Beneficiary.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/web/api/service/DefaultActivityPlanService.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/java/org/hisp/dhis/patient/action/patientattribute/AddPatientAttributeAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/java/org/hisp/dhis/patient/action/patientattribute/GetPatientAttributeAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/java/org/hisp/dhis/patient/action/patientattribute/UpdatePatientAttributeAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/resources/org/hisp/dhis/patient/i18n_module.properties
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/resources/org/hisp/dhis/patient/i18n_module_vi_VN.properties
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/webapp/dhis-web-maintenance-patient/addPatientAttributeForm.vm
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/webapp/dhis-web-maintenance-patient/updatePatientAttibuteForm.vm


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientAttribute.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientAttribute.java	2010-06-23 19:59:35 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientAttribute.java	2010-11-12 10:28:30 +0000
@@ -44,7 +44,7 @@
     public static final String TYPE_INT = "NUMBER";
 
     public static final String TYPE_BOOL = "YES/NO";
-    
+
     public static final String TYPE_COMBO = "COMBO";
 
     private int id;
@@ -54,13 +54,15 @@
     private String description;
 
     private String valueType;
-    
+
     private boolean mandatory;
-    
+
     private boolean inheritable;
-    
+
+    private Boolean groupBy;
+
     private PatientAttributeGroup patientAttributeGroup;
-    
+
     private Set<PatientAttributeOption> attributeOptions;
 
     // -------------------------------------------------------------------------
@@ -113,7 +115,7 @@
     // -------------------------------------------------------------------------
     // Getters and setters
     // -------------------------------------------------------------------------
-    
+
     public Set<PatientAttributeOption> getAttributeOptions()
     {
         return attributeOptions == null ? new HashSet<PatientAttributeOption>() : attributeOptions;
@@ -123,13 +125,28 @@
     {
         this.attributeOptions = attributeOptions;
     }
-    
+
     public void addAttributeOptions( PatientAttributeOption option )
     {
-        if( attributeOptions == null )
+        if ( attributeOptions == null )
             attributeOptions = new HashSet<PatientAttributeOption>();
         attributeOptions.add( option );
     }
+
+    public Boolean isGroupBy()
+    {
+        return groupBy;
+    }
+
+    public void setGroupBy( Boolean groupBy )
+    {
+        this.groupBy = groupBy;
+    }
+
+    public Boolean getGroupBy()
+    {
+        return groupBy;
+    }
     
     public int getId()
     {
@@ -191,12 +208,14 @@
         this.patientAttributeGroup = patientAttributeGroup;
     }
 
-	public boolean isInheritable() {
-		return inheritable;
-	}
+    public boolean isInheritable()
+    {
+        return inheritable;
+    }
 
-	public void setInheritable(boolean inheritable) {
-		this.inheritable = inheritable;
-	}
+    public void setInheritable( boolean inheritable )
+    {
+        this.inheritable = inheritable;
+    }
 
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientAttributeService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientAttributeService.java	2010-11-09 02:09:53 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientAttributeService.java	2010-11-12 10:28:30 +0000
@@ -55,5 +55,7 @@
     Collection<PatientAttribute> getOptionalPatientAttributesWithoutGroup();
     
     Collection<PatientAttribute> getPatientAttributesByMandatory(boolean mandatory);
+    
+    PatientAttribute getPatientAttributeByGroupBy(boolean groupBy);
 
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientAttributeStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientAttributeStore.java	2010-02-22 09:19:15 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientAttributeStore.java	2010-11-12 10:28:30 +0000
@@ -47,4 +47,6 @@
     Collection<PatientAttribute> getPatientAttributesByMandatory(boolean mandatory);
     
     Collection<PatientAttribute> getPatientAttributesNotGroup();
+
+    PatientAttribute getByGroupBy( boolean groupBy );
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java	2010-10-28 09:17:13 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/TableAlteror.java	2010-11-12 10:28:30 +0000
@@ -162,7 +162,11 @@
         {
             executeSql( "UPDATE patientattribute SET mandatory=false" );
         }
-
+        
+        if ( executeSql( "ALTER TABLE patientattribute ADD groupby bool" ) >= 0){
+            executeSql( "UPDATE patientattribute SET groupby=false" );
+        }
+        
         // update periodType field to ValidationRule
         executeSql( "UPDATE validationrule SET periodtypeid = (SELECT periodtypeid FROM periodtype WHERE name='Monthly')" );
 

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/DefaultPatientAttributeService.java'
--- dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/DefaultPatientAttributeService.java	2010-02-22 09:19:15 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/DefaultPatientAttributeService.java	2010-11-12 10:28:30 +0000
@@ -87,6 +87,11 @@
     {
         return patientAttributeStore.getByName( name );
     }
+    
+    public PatientAttribute getPatientAttributeByGroupBy( boolean groupBy )
+    {
+        return patientAttributeStore.getByGroupBy( groupBy );
+    }
 
     public Collection<PatientAttribute> getOptionalPatientAttributesWithoutGroup()
     {

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/hibernate/HibernatePatientAttributeStore.java'
--- dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/hibernate/HibernatePatientAttributeStore.java	2010-02-22 09:19:15 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/hibernate/HibernatePatientAttributeStore.java	2010-11-12 10:28:30 +0000
@@ -67,4 +67,8 @@
         return getCriteria( Restrictions.isNull( "patientAttributeGroup" ) ).list();
     }
     
+    public PatientAttribute getByGroupBy( boolean groupBy ){
+        return (PatientAttribute)getCriteria( Restrictions.eq( "groupBy", groupBy ) ).uniqueResult();
+    }
+    
 }

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/resources/org/hisp/dhis/patient/hibernate/PatientAttribute.hbm.xml'
--- dhis-2/dhis-services/dhis-service-patient/src/main/resources/org/hisp/dhis/patient/hibernate/PatientAttribute.hbm.xml	2010-09-22 06:44:36 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/resources/org/hisp/dhis/patient/hibernate/PatientAttribute.hbm.xml	2010-11-12 10:28:30 +0000
@@ -18,6 +18,8 @@
 	<property name="mandatory" column="mandatory" not-null="true" />
 	
 	<property name="inheritable" column="inheritable" />
+	
+	<property name="groupBy" column="groupby" />
     
     <many-to-one name="patientAttributeGroup" column="patientattributegroupid"
 			class="org.hisp.dhis.patient.PatientAttributeGroup"

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/web/api/model/ActivityPlan.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/web/api/model/ActivityPlan.java	2010-11-01 06:32:22 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/web/api/model/ActivityPlan.java	2010-11-12 10:28:30 +0000
@@ -11,7 +11,8 @@
 import javax.xml.bind.annotation.XmlRootElement;
 
 @XmlRootElement
-public class ActivityPlan implements ISerializable
+public class ActivityPlan
+    implements ISerializable
 {
 
     private List<Activity> activitiesList;
@@ -27,60 +28,64 @@
         this.activitiesList = activitiesList;
     }
 
-	@Override
-	public byte[] serialize() throws IOException {
-		
-		ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        DataOutputStream dout = new DataOutputStream(bout);
-        
-        dout.writeInt(this.getActivitiesList().size());
-
-        for(int i=0; i<activitiesList.size(); i++)
+    @Override
+    public byte[] serialize()
+        throws IOException
+    {
+
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        DataOutputStream dout = new DataOutputStream( bout );
+
+        dout.writeInt( this.getActivitiesList().size() );
+
+        for ( int i = 0; i < activitiesList.size(); i++ )
         {
-            Activity activity = (Activity)activitiesList.get(i);
-            activity.serialize(dout);            
+            Activity activity = (Activity) activitiesList.get( i );
+            activity.serialize( dout );
         }
 
         return bout.toByteArray();
-	}
-	
-	public void serialize( OutputStream out ) throws IOException
+    }
+
+    public void serialize( OutputStream out )
+        throws IOException
     {
-    	ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        DataOutputStream dout = new DataOutputStream(bout);       
-        
-        if(activitiesList == null){
-        	dout.writeInt(0);
-        }else{
-        	dout.writeInt(activitiesList.size());
-	        for(int i=0; i<activitiesList.size(); i++)
-	        {
-	        	Activity activity = (Activity)activitiesList.get(i);
-	        	dout.writeLong(activity.getDueDate().getTime());
-	        	Beneficiary b = activity.getBeneficiary();
-	        	dout.writeInt(b.getId()); 
-	        	dout.writeUTF(b.getFirstName()); 
-	        	dout.writeUTF(b.getMiddleName()); 
-	        	dout.writeUTF(b.getLastName());
-	        	dout.writeBoolean(activity.isLate());
-	        	Set<String> atts = b.getPatientAttValues();
-	                dout.writeInt( atts.size() );
-	                for(String att : atts){
-	                    dout.writeUTF( att );
-	                }
-	        	Task t = activity.getTask();
-	        	dout.writeInt(t.getId()); dout.writeInt(t.getProgramStageId()); dout.writeBoolean(t.isCompleted());           
-	        }
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        DataOutputStream dout = new DataOutputStream( bout );
+
+        if ( activitiesList == null )
+        {
+            dout.writeInt( 0 );
+        }
+        else
+        {
+            dout.writeInt( activitiesList.size() );
+            for ( int i = 0; i < activitiesList.size(); i++ )
+            {
+                Activity activity = (Activity) activitiesList.get( i );
+                dout.writeLong( activity.getDueDate().getTime() );
+                dout.writeBoolean( activity.isLate() );
+
+                Beneficiary b = activity.getBeneficiary();
+                b.serialize( dout );
+                
+                Task t = activity.getTask();
+                dout.writeInt( t.getId() );
+                dout.writeInt( t.getProgramStageId() );
+                dout.writeBoolean( t.isCompleted() );
+            }
         }
         bout.flush();
-        bout.writeTo(out);
-    	
-    } 
-
-	@Override
-	public void deSerialize(byte[] data) throws IOException {
-		// TODO Auto-generated method stub
-		
-	}
+        bout.writeTo( out );
+
+    }
+
+    @Override
+    public void deSerialize( byte[] data )
+        throws IOException
+    {
+        // TODO Auto-generated method stub
+
+    }
 
 }

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/web/api/model/Beneficiary.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/web/api/model/Beneficiary.java	2010-10-19 09:32:21 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/web/api/model/Beneficiary.java	2010-11-12 10:28:30 +0000
@@ -10,7 +10,8 @@
 import javax.xml.bind.annotation.XmlRootElement;
 
 @XmlRootElement
-public class Beneficiary implements ISerializable
+public class Beneficiary
+    implements ISerializable
 {
     private int id;
 
@@ -19,13 +20,21 @@
     private String middleName;
 
     private String lastName;
-    
+
     private Set<String> patientAttValues;
-    
-    
-
-    
-    
+
+    private PatientAttribute groupAttribute;
+
+    public PatientAttribute getGroupAttribute()
+    {
+        return groupAttribute;
+    }
+
+    public void setGroupAttribute( PatientAttribute groupAttribute )
+    {
+        this.groupAttribute = groupAttribute;
+    }
+
     public Set<String> getPatientAttValues()
     {
         return patientAttValues;
@@ -80,40 +89,52 @@
         this.lastName = lastName;
     }
 
-	public byte[] serialize() throws IOException {
-		// TODO Auto-generated method stub
-		return null;
-	}
-	
-	public void serialize( DataOutputStream dout ) throws IOException
-    {		
-		dout.writeInt(this.getId());
-        dout.writeUTF(this.getFirstName());        
-        dout.writeUTF(this.getMiddleName());
-        dout.writeUTF(this.getLastName());
-                
-        dout.flush();            	
+    public byte[] serialize()
+        throws IOException
+    {
+        // TODO Auto-generated method stub
+        return null;
     }
-	
-	public void serialize( OutputStream out ) throws IOException
+
+    public void serialize( DataOutputStream out )
+        throws IOException
     {
-    	ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        DataOutputStream dout = new DataOutputStream(bout);
-        
-        dout.writeInt(this.getId());
-        dout.writeUTF(this.getFirstName());        
-        dout.writeUTF(this.getMiddleName());
-        dout.writeUTF(this.getLastName());     
-        
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        DataOutputStream dout = new DataOutputStream( bout );
+
+        dout.writeInt( this.getId() );
+        dout.writeUTF( this.getFirstName() );
+        dout.writeUTF( this.getMiddleName() );
+        dout.writeUTF( this.getLastName() );
+        //Write attribute which is used as group factor of beneficiary.
+        /* False: no group factor
+         * True: with group factor
+         * */
+        if ( this.getGroupAttribute() != null )
+        {
+            dout.writeBoolean( true );
+            this.getGroupAttribute().serialize( dout );
+        }
+        else
+        {
+            dout.writeBoolean( false );
+        }
+
+        Set<String> atts = this.getPatientAttValues();
+        dout.writeInt( atts.size() );
+        for ( String att : atts )
+        {
+            dout.writeUTF( att );
+        }
+
         bout.flush();
-        bout.writeTo(out);
-    	
-    } 
-	
-	public void deSerialize(byte[] data) throws IOException {
-		// TODO Auto-generated method stub		
-	}
+        bout.writeTo( out );
+    }
 
-    
+    public void deSerialize( byte[] data )
+        throws IOException
+    {
+        // TODO Auto-generated method stub
+    }
 
 }

=== added file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/web/api/model/PatientAttribute.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/web/api/model/PatientAttribute.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/web/api/model/PatientAttribute.java	2010-11-12 10:28:30 +0000
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2004-2009, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software without
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.hisp.dhis.web.api.model;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class PatientAttribute
+{
+
+    private String name;
+
+    private String value;
+
+    // -------------------------------------------------------------------------
+    // Constructors
+    // -------------------------------------------------------------------------
+    public PatientAttribute()
+    {
+    }
+
+    // -------------------------------------------------------------------------
+    // Getter & Setter
+    // -------------------------------------------------------------------------
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+    public String getValue()
+    {
+        return value;
+    }
+
+    public void setValue( String value )
+    {
+        this.value = value;
+    }
+
+    public void serialize( DataOutputStream out )
+        throws IOException
+    {
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        DataOutputStream dout = new DataOutputStream( bout );
+        
+        dout.writeUTF( this.name );
+        dout.writeUTF( this.value );
+        
+        bout.flush();
+        bout.writeTo( out );
+    }
+
+}

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/web/api/service/DefaultActivityPlanService.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/web/api/service/DefaultActivityPlanService.java	2010-11-09 02:53:08 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/web/api/service/DefaultActivityPlanService.java	2010-11-12 10:28:30 +0000
@@ -12,11 +12,13 @@
 import org.hisp.dhis.activityplan.Activity;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.patient.Patient;
+import org.hisp.dhis.patient.PatientAttributeService;
 import org.hisp.dhis.patientattributevalue.PatientAttributeValue;
 import org.hisp.dhis.patientattributevalue.PatientAttributeValueService;
 import org.hisp.dhis.user.CurrentUserService;
 import org.hisp.dhis.web.api.model.ActivityPlan;
 import org.hisp.dhis.web.api.model.Beneficiary;
+import org.hisp.dhis.web.api.model.PatientAttribute;
 import org.hisp.dhis.web.api.service.mapping.ActivitiesMapper;
 import org.hisp.dhis.web.api.service.mapping.TaskMapper;
 import org.joda.time.DateMidnight;
@@ -42,6 +44,9 @@
     private PatientAttributeValueService patientAttValueService;
 
     @Autowired
+    private PatientAttributeService patientAttService;
+
+    @Autowired
     private CurrentUserService currentUserService;
 
     // -------------------------------------------------------------------------
@@ -105,6 +110,7 @@
         }
 
         return plan;
+
     }
 
     private org.hisp.dhis.web.api.model.Activity getActivityModel( org.hisp.dhis.activityplan.Activity activity )
@@ -134,6 +140,21 @@
         beneficiary.setLastName( patient.getLastName() );
         beneficiary.setMiddleName( patient.getMiddleName() );
 
+        // Set attribute which is used to group beneficiary on mobile (only if there is attribute which is set to be group factor)
+        PatientAttribute beneficiaryAttribute = null;
+        org.hisp.dhis.patient.PatientAttribute patientAttribute = patientAttService.getPatientAttributeByGroupBy( true );
+
+        if ( patientAttribute != null )
+        {
+            beneficiaryAttribute = new PatientAttribute();
+            beneficiaryAttribute.setName( patientAttribute.getName() );
+            beneficiaryAttribute.setValue( patientAttValueService.getPatientAttributeValue( patient, patientAttribute )
+                .getValue() );
+            beneficiary.setGroupAttribute( beneficiaryAttribute );
+        }
+        patientAttribute = null;        
+
+        // Set all attributes
         for ( PatientAttributeValue value : patientAttValueService.getPatientAttributeValues( patient ) )
         {
             patientAttValues.add( value.getPatientAttribute().getName() + " : " + value.getValue() );

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/java/org/hisp/dhis/patient/action/patientattribute/AddPatientAttributeAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/java/org/hisp/dhis/patient/action/patientattribute/AddPatientAttributeAction.java	2010-09-26 11:49:41 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/java/org/hisp/dhis/patient/action/patientattribute/AddPatientAttributeAction.java	2010-11-12 10:28:30 +0000
@@ -43,7 +43,7 @@
 public class AddPatientAttributeAction
     implements Action
 {
-	 // -------------------------------------------------------------------------
+    // -------------------------------------------------------------------------
     // Dependencies
     // -------------------------------------------------------------------------
 
@@ -52,10 +52,10 @@
     public void setPatientAttributeService( PatientAttributeService patientAttributeService )
     {
         this.patientAttributeService = patientAttributeService;
-    }   
-    
+    }
+
     private PatientAttributeOptionService patientAttributeOptionService;
-    
+
     public void setPatientAttributeOptionService( PatientAttributeOptionService patientAttributeOptionService )
     {
         this.patientAttributeOptionService = patientAttributeOptionService;
@@ -85,28 +85,35 @@
     {
         this.valueType = valueType;
     }
-    
+
     private boolean mandatory;
-    
+
     public void setMandatory( boolean mandatory )
     {
         this.mandatory = mandatory;
     }
-    
+
     private boolean inheritable;
-    
+
     public void setInheritable( boolean inheritable )
     {
         this.inheritable = inheritable;
     }
-    
+
     private List<String> attrOptions;
-    
+
     public void setAttrOptions( List<String> attrOptions )
     {
         this.attrOptions = attrOptions;
     }
 
+    private boolean groupBy;
+
+    public void setGroupBy( boolean groupBy )
+    {
+        this.groupBy = groupBy;
+    }
+
     // -------------------------------------------------------------------------
     // Action implementation
     // -------------------------------------------------------------------------
@@ -121,13 +128,22 @@
         patientAttribute.setValueType( valueType );
         patientAttribute.setMandatory( mandatory );
         patientAttribute.setInheritable( inheritable );
-        
+        patientAttribute.setGroupBy( groupBy );
+        if ( groupBy == true )
+        {
+            PatientAttribute patientAtt = patientAttributeService.getPatientAttributeByGroupBy( true );
+            if ( patientAtt != null )
+            {
+                patientAtt.setGroupBy( false );
+                patientAttributeService.updatePatientAttribute( patientAtt );
+            }
+        }
         patientAttributeService.savePatientAttribute( patientAttribute );
-        
-        if( PatientAttribute.TYPE_COMBO.equalsIgnoreCase( valueType ) )
+
+        if ( PatientAttribute.TYPE_COMBO.equalsIgnoreCase( valueType ) )
         {
-            PatientAttributeOption opt  = null;
-            for( String optionName : attrOptions )
+            PatientAttributeOption opt = null;
+            for ( String optionName : attrOptions )
             {
                 opt = new PatientAttributeOption();
                 opt.setName( optionName );
@@ -136,8 +152,7 @@
                 patientAttributeOptionService.addPatientAttributeOption( opt );
             }
         }
-        
-        
+
         return SUCCESS;
     }
 }
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/java/org/hisp/dhis/patient/action/patientattribute/GetPatientAttributeAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/java/org/hisp/dhis/patient/action/patientattribute/GetPatientAttributeAction.java	2009-10-22 07:41:39 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/java/org/hisp/dhis/patient/action/patientattribute/GetPatientAttributeAction.java	2010-11-12 10:28:30 +0000
@@ -77,6 +77,7 @@
     {
         patientAttribute = patientAttributeService.getPatientAttribute( id );
 
+
         return SUCCESS;
     }
 }

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/java/org/hisp/dhis/patient/action/patientattribute/UpdatePatientAttributeAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/java/org/hisp/dhis/patient/action/patientattribute/UpdatePatientAttributeAction.java	2010-09-26 11:49:41 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/java/org/hisp/dhis/patient/action/patientattribute/UpdatePatientAttributeAction.java	2010-11-12 10:28:30 +0000
@@ -48,7 +48,8 @@
 public class UpdatePatientAttributeAction
     implements Action
 {
-	public static final String PREFIX_ATTRIBUTE_OPTION = "attrOption";
+    public static final String PREFIX_ATTRIBUTE_OPTION = "attrOption";
+
     // -------------------------------------------------------------------------
     // Dependencies
     // -------------------------------------------------------------------------
@@ -59,9 +60,9 @@
     {
         this.patientAttributeService = patientAttributeService;
     }
-    
+
     private PatientAttributeOptionService patientAttributeOptionService;
-    
+
     public void setPatientAttributeOptionService( PatientAttributeOptionService patientAttributeOptionService )
     {
         this.patientAttributeOptionService = patientAttributeOptionService;
@@ -105,21 +106,28 @@
     {
         this.mandatory = mandatory;
     }
-    
+
     private boolean inheritable;
-    
+
     public void setInheritable( boolean inheritable )
     {
         this.inheritable = inheritable;
     }
-    
+
     private List<String> attrOptions;
-    
+
     public void setAttrOptions( List<String> attrOptions )
     {
         this.attrOptions = attrOptions;
     }
 
+    private boolean groupBy;
+
+    public void setGroupBy( boolean groupBy )
+    {
+        this.groupBy = groupBy;
+    }
+
     // -------------------------------------------------------------------------
     // Action implementation
     // -------------------------------------------------------------------------
@@ -127,51 +135,61 @@
     public String execute()
         throws Exception
     {
-    	 PatientAttribute patientAttribute = patientAttributeService.getPatientAttribute( id );
-
-         patientAttribute.setName( name );
-         patientAttribute.setDescription( description );
-         patientAttribute.setValueType( valueType );
-         patientAttribute.setMandatory( mandatory );
-         patientAttribute.setInheritable( inheritable );
-
-         HttpServletRequest request = ServletActionContext.getRequest();
-         
-         Collection<PatientAttributeOption> attributeOptions = patientAttributeOptionService.get( patientAttribute );
-         
-         if ( attributeOptions != null && attributeOptions.size() > 0 )
-         {
-             String value = null;
-             for( PatientAttributeOption option : attributeOptions )
-             {
-                 value = request.getParameter( PREFIX_ATTRIBUTE_OPTION + option.getId() );
-                 if ( StringUtils.isNotBlank( value ) )
-                 {
-                     option.setName( value.trim() );
-                     patientAttributeOptionService.updatePatientAttributeOption( option );
-                 }
-             }
-         }
-         
-         if( attrOptions != null )
-         {
-             PatientAttributeOption opt  = null;
-             for( String optionName : attrOptions )
-             {
-                 opt = patientAttributeOptionService.get( patientAttribute, optionName );
-                 if( opt == null )
-                 {
-                     opt = new PatientAttributeOption();
-                     opt.setName( optionName );
-                     opt.setPatientAttribute( patientAttribute );
-                     patientAttribute.addAttributeOptions( opt );
-                     patientAttributeOptionService.addPatientAttributeOption( opt );
-                 }
-             }
-         }
-         
-         patientAttributeService.updatePatientAttribute( patientAttribute );
-         
-         return SUCCESS; 
+        PatientAttribute patientAttribute = patientAttributeService.getPatientAttribute( id );
+
+        patientAttribute.setName( name );
+        patientAttribute.setDescription( description );
+        patientAttribute.setValueType( valueType );
+        patientAttribute.setMandatory( mandatory );
+        patientAttribute.setInheritable( inheritable );
+
+        if ( groupBy == true )
+        {
+            PatientAttribute patientAtt = patientAttributeService.getPatientAttributeByGroupBy( true );
+            if ( patientAtt != null )
+            {
+                patientAtt.setGroupBy( false );
+                patientAttributeService.updatePatientAttribute( patientAtt );
+            }
+        }
+        patientAttribute.setGroupBy( groupBy );
+        HttpServletRequest request = ServletActionContext.getRequest();
+
+        Collection<PatientAttributeOption> attributeOptions = patientAttributeOptionService.get( patientAttribute );
+
+        if ( attributeOptions != null && attributeOptions.size() > 0 )
+        {
+            String value = null;
+            for ( PatientAttributeOption option : attributeOptions )
+            {
+                value = request.getParameter( PREFIX_ATTRIBUTE_OPTION + option.getId() );
+                if ( StringUtils.isNotBlank( value ) )
+                {
+                    option.setName( value.trim() );
+                    patientAttributeOptionService.updatePatientAttributeOption( option );
+                }
+            }
+        }
+
+        if ( attrOptions != null )
+        {
+            PatientAttributeOption opt = null;
+            for ( String optionName : attrOptions )
+            {
+                opt = patientAttributeOptionService.get( patientAttribute, optionName );
+                if ( opt == null )
+                {
+                    opt = new PatientAttributeOption();
+                    opt.setName( optionName );
+                    opt.setPatientAttribute( patientAttribute );
+                    patientAttribute.addAttributeOptions( opt );
+                    patientAttributeOptionService.addPatientAttributeOption( opt );
+                }
+            }
+        }
+
+        patientAttributeService.updatePatientAttribute( patientAttribute );
+
+        return SUCCESS;
     }
 }

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/resources/org/hisp/dhis/patient/i18n_module.properties'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/resources/org/hisp/dhis/patient/i18n_module.properties	2010-11-09 06:45:07 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/resources/org/hisp/dhis/patient/i18n_module.properties	2010-11-12 10:28:30 +0000
@@ -1,3 +1,6 @@
+yes = Yes
+no = No
+groupBy = Group By
 filters = Filters
 any = Any
 equal_to = Equal

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/resources/org/hisp/dhis/patient/i18n_module_vi_VN.properties'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/resources/org/hisp/dhis/patient/i18n_module_vi_VN.properties	2010-10-14 08:54:26 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/resources/org/hisp/dhis/patient/i18n_module_vi_VN.properties	2010-11-12 10:28:30 +0000
@@ -1,3 +1,6 @@
+yes = Co
+no = Khong
+groupBy = Chi muc nhom
 invalid_date = Ng\u00e0y kh\u00f4ng h\u1ee3p l\u1ec7
 duplicate_names = T\u00ean b\u1ecb tr\u00f9ng l\u1eb7p
 removing_relationship_failed = L\u1ed7i trong khi g\u1ee1 b\u1ecf M\u1ed1i quan h\u1ec7

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/webapp/dhis-web-maintenance-patient/addPatientAttributeForm.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/webapp/dhis-web-maintenance-patient/addPatientAttributeForm.vm	2010-09-26 11:49:41 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/webapp/dhis-web-maintenance-patient/addPatientAttributeForm.vm	2010-11-12 10:28:30 +0000
@@ -84,6 +84,10 @@
         </td>
         <td></td>
     </tr>  
+    <tr>
+    	<td width="20em"><label for="groupBy">$i18n.getString( "groupBy" )</td>
+    	<td><input type="checkbox" name="groupBy" value="true"></td>
+    </tr>
     <tr id="attributeComboRow"> 
     	<td width="20em"><label>$i18n.getString( "attribute_options" ) <em title="$i18n.getString( "required" )" class="required">*</em></label></td>
     	<td ><table id="attrOptionContainer"></table><a href="#" style="text-decoration: none;margin-top: 0.5em"  onclick="ATTRIBUTE_OPTION.addOption()">[ $i18n.getString( "add_more_option" ) ]</a>

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/webapp/dhis-web-maintenance-patient/updatePatientAttibuteForm.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/webapp/dhis-web-maintenance-patient/updatePatientAttibuteForm.vm	2010-11-08 06:45:31 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/webapp/dhis-web-maintenance-patient/updatePatientAttibuteForm.vm	2010-11-12 10:28:30 +0000
@@ -85,6 +85,10 @@
             </select>
         </td>
       </tr>
+      <tr>
+    	<td width="20em"><label for="groupBy">$i18n.getString( "groupBy" )</td>
+    	<td><input type="checkbox" name="groupBy" value="true" #if( $patientAttribute.groupBy == 'true' ) checked #end></td>
+      </tr>
       <tr id="attributeComboRow"> 
     	<td width="20em"><label>$i18n.getString( "attribute_options" ) <em title="$i18n.getString( "required" )" class="required">*</em></label></td>
     	<td >