← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 13537: Minor changes to web api - notes as patientcomment are now sent through events, attributes can no...

 

Merge authors:
  Abyot Asalefew Gizaw abyota@xxxxxxxxx
------------------------------------------------------------
revno: 13537 [merge]
committer: Abyot Asalefew Gizaw abyota@xxxxxxxxx
branch nick: dhis2
timestamp: Thu 2014-01-02 14:13:21 +0100
message:
  Minor changes to web api - notes as patientcomment are now sent through events, attributes can now be filtered as registration attributes and those linked with programs (or enrollment attributes), patientcomment is also attached to programinstance and now it is possible to have multiple comments as it is important to keep journal of patient comments
added:
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/Note.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElement.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientAttributeService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstance.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStage.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageDataElement.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageInstance.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/AbstractEventService.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/Event.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/startup/TableAlteror.java
  dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/DefaultProgramInstanceService.java
  dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/ProgramInstanceDeletionHandler.java
  dhis-2/dhis-services/dhis-service-patient/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-services/dhis-service-patient/src/main/resources/org/hisp/dhis/program/hibernate/ProgramInstance.hbm.xml
  dhis-2/dhis-services/dhis-service-patient/src/main/resources/org/hisp/dhis/program/hibernate/ProgramStageInstance.hbm.xml
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/event/PersonAttributeTypeController.java
  dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/caseentry/SaveProgramInstanceCommentAction.java
  dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/reminder/SavePatientCommentAction.java
  dhis-2/dhis-web/dhis-web-caseentry/src/main/resources/META-INF/dhis/beans.xml


--
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/dataelement/DataElement.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElement.java	2013-12-03 17:53:29 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElement.java	2014-01-02 13:13:21 +0000
@@ -628,7 +628,6 @@
     }
 
     @JsonProperty
-    @JsonSerialize( as = BaseIdentifiableObject.class )
     @JsonView( { DetailedView.class, ExportView.class } )
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0)
     public OptionSet getOptionSet()

=== 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	2013-11-05 09:31:47 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/patient/PatientAttributeService.java	2013-12-12 15:17:55 +0000
@@ -138,5 +138,12 @@
      * @return List of patient attributes
      */
     Collection<PatientAttribute> getPatientAttributesByDisplayOnVisitSchedule( boolean displayOnVisitSchedule );
+    
+    /**
+     * Get patient attributes without Program
+     * 
+     * @return List of patient attributes without Program
+     */
+    Collection<PatientAttribute> getPatientAttributesWithoutProgram();
 
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstance.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstance.java	2013-11-14 08:17:57 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramInstance.java	2013-12-16 08:29:52 +0000
@@ -80,7 +80,7 @@
     private Patient patient;
 
     private Program program;
-
+    
     private Set<ProgramStageInstance> programStageInstances = new HashSet<ProgramStageInstance>();
 
     private List<OutboundSms> outboundSms;
@@ -89,7 +89,7 @@
 
     private Boolean followup = false;
 
-    private PatientComment patientComment;
+    private Set<PatientComment> patientComments = new HashSet<PatientComment>();
 
     // -------------------------------------------------------------------------
     // Constructors
@@ -383,16 +383,14 @@
     @JsonProperty
     @JsonView( { DetailedView.class, ExportView.class } )
     @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 )
-    public PatientComment getPatientComment()
-    {
-        return patientComment;
-    }
-
-    public void setPatientComment( PatientComment patientComment )
-    {
-        this.patientComment = patientComment;
-    }
-
+    public Set<PatientComment> getPatientComments() {
+		return patientComments;
+	}
+
+	public void setPatientComments(Set<PatientComment> patientComments) {
+		this.patientComments = patientComments;
+	}
+    
     public List<MessageConversation> getMessageConversations()
     {
         return messageConversations;
@@ -401,5 +399,5 @@
     public void setMessageConversations( List<MessageConversation> messageConversations )
     {
         this.messageConversations = messageConversations;
-    }
+    }		
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStage.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStage.java	2013-12-31 03:05:28 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStage.java	2014-01-02 13:13:21 +0000
@@ -198,11 +198,10 @@
         return description;
     }
 
-    @JsonProperty( value = "validationCriterias" )
-    @JsonSerialize( contentAs = BaseIdentifiableObject.class )
+    @JsonProperty( value = "programStageSections" )
     @JsonView( { DetailedView.class, ExportView.class } )
-    @JacksonXmlElementWrapper( localName = "validationCriterias", namespace = DxfNamespaces.DXF_2_0 )
-    @JacksonXmlProperty( localName = "validationCriteria", namespace = DxfNamespaces.DXF_2_0 )
+    @JacksonXmlElementWrapper( localName = "programStageSections", namespace = DxfNamespaces.DXF_2_0 )
+    @JacksonXmlProperty( localName = "programStageSection", namespace = DxfNamespaces.DXF_2_0 )
     public Set<ProgramStageSection> getProgramStageSections()
     {
         return programStageSections;

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageDataElement.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageDataElement.java	2013-12-17 12:25:25 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageDataElement.java	2014-01-02 13:13:21 +0000
@@ -30,10 +30,8 @@
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonView;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
-import org.hisp.dhis.common.BaseIdentifiableObject;
 import org.hisp.dhis.common.DxfNamespaces;
 import org.hisp.dhis.common.view.DetailedView;
 import org.hisp.dhis.common.view.ExportView;
@@ -102,10 +100,6 @@
     {
     }
 
-    @JsonProperty
-    @JsonView( { DetailedView.class, ExportView.class } )
-    @JsonSerialize( as = BaseIdentifiableObject.class )
-    @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 )
     public ProgramStage getProgramStage()
     {
         return programStage;

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageInstance.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageInstance.java	2013-11-25 06:30:47 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageInstance.java	2013-12-16 08:29:52 +0000
@@ -31,7 +31,6 @@
 import org.hisp.dhis.common.BaseIdentifiableObject;
 import org.hisp.dhis.message.MessageConversation;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
-import org.hisp.dhis.patientcomment.PatientComment;
 import org.hisp.dhis.sms.outbound.OutboundSms;
 
 import java.util.Calendar;
@@ -41,6 +40,10 @@
 /**
  * @author Abyot Asalefew
  */
+/**
+ * @author abyot
+ *
+ */
 public class ProgramStageInstance
     extends BaseIdentifiableObject
 {
@@ -77,8 +80,6 @@
 
     private List<MessageConversation> messageConversations;
 
-    private PatientComment patientComment;
-
     private Integer status = ACTIVE_STATUS;
 
     private Double longitude;
@@ -264,16 +265,6 @@
         this.outboundSms = outboundSms;
     }
 
-    public PatientComment getPatientComment()
-    {
-        return patientComment;
-    }
-
-    public void setPatientComment( PatientComment patientComment )
-    {
-        this.patientComment = patientComment;
-    }
-
     public Date getCompletedDate()
     {
         return completedDate;
@@ -322,9 +313,9 @@
     public void setLatitude( Double latitude )
     {
         this.latitude = latitude;
-    }
+    }  
 
-    public Integer getEventStatus()
+	public Integer getEventStatus()
     {
         if ( this.status != 0 )
         {

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/AbstractEventService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/AbstractEventService.java	2013-12-30 12:36:02 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/AbstractEventService.java	2014-01-02 11:35:24 +0000
@@ -28,6 +28,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -36,6 +37,7 @@
 import java.util.List;
 import java.util.Set;
 
+
 import org.hisp.dhis.common.IdentifiableObjectManager;
 import org.hisp.dhis.dataelement.DataElement;
 import org.hisp.dhis.dataelement.DataElementService;
@@ -50,6 +52,8 @@
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.patient.Patient;
 import org.hisp.dhis.patient.PatientService;
+import org.hisp.dhis.patientcomment.PatientComment;
+import org.hisp.dhis.patientcomment.PatientCommentService;
 import org.hisp.dhis.patientdatavalue.PatientDataValue;
 import org.hisp.dhis.patientdatavalue.PatientDataValueService;
 import org.hisp.dhis.program.Program;
@@ -106,6 +110,9 @@
 
     @Autowired
     private PatientService patientService;
+    
+    @Autowired
+    private PatientCommentService patientCommentService;
 
     @Autowired
     private IdentifiableObjectManager manager;
@@ -441,7 +448,7 @@
         {
             organisationUnit = programStageInstance.getOrganisationUnit();
         }
-
+        
         Date date = new Date();
 
         String storedBy = getStoredBy( event, null );
@@ -449,9 +456,13 @@
         programStageInstance.setDueDate( date );
         programStageInstance.setExecutionDate( date );
         programStageInstance.setOrganisationUnit( organisationUnit );
-        programStageInstance.setCompletedUser( storedBy );
-
+        programStageInstance.setCompletedUser( storedBy );       
+        
         programStageInstanceService.updateProgramStageInstance( programStageInstance );
+        
+        ProgramInstance programInstance = programStageInstance.getProgramInstance();
+        
+        savePatientCommentFromEvent( programInstance, event, storedBy );
 
         Set<PatientDataValue> patientDataValues = new HashSet<PatientDataValue>(
             patientDataValueService.getPatientDataValues( programStageInstance ) );
@@ -514,6 +525,7 @@
         Event event = new Event();
 
         event.setEvent( programStageInstance.getUid() );
+        event.setPerson( programStageInstance.getProgramInstance().getPatient().getUid());
         event.setStatus( EventStatus.fromInt( programStageInstance.getStatus() ) );
         event.setEventDate( programStageInstance.getExecutionDate().toString() );
         event.setStoredBy( programStageInstance.getCompletedUser() );
@@ -561,7 +573,20 @@
             value.setStoredBy( patientDataValue.getStoredBy() );
 
             event.getDataValues().add( value );
-        }
+        }        
+        
+        ProgramInstance programInstance = programStageInstance.getProgramInstance();
+        
+        Collection<PatientComment> patientComments = programInstance.getPatientComments();
+        
+        for( PatientComment patientComment : patientComments )
+        {   
+        	Note note = new Note();
+        	note.setValue( patientComment.getCommentText() );
+        	note.setStoredBy( patientComment.getCreator() );
+        	note.setStoredDate( patientComment.getCreatedDate().toString() );
+        	event.getNotes().add( note );
+        }       
 
         return event;
     }
@@ -729,13 +754,14 @@
         }
 
         String storedBy = getStoredBy( event, importSummary );
-
+        
         if ( !dryRun )
         {
             if ( programStageInstance == null )
             {
                 programStageInstance = createProgramStageInstance( programStage, programInstance, organisationUnit,
-                    eventDate, EventStatus.COMPLETED.equals( event.getStatus() ), event.getCoordinate(), storedBy );
+                    eventDate, EventStatus.COMPLETED.equals( event.getStatus() ), event.getCoordinate(), storedBy );             
+                
             }
             else
             {
@@ -743,6 +769,8 @@
                     EventStatus.COMPLETED.equals( event.getStatus() ), event.getCoordinate(), storedBy,
                     programStageInstance );
             }
+            
+            savePatientCommentFromEvent( programInstance, event, storedBy );
 
             importSummary.setReference( programStageInstance.getUid() );
         }
@@ -776,4 +804,21 @@
 
         return importSummary;
     }
+    
+    private void savePatientCommentFromEvent(ProgramInstance programInstance, Event event, String storedBy)
+    {
+    	for( Note note : event.getNotes() ) //only one note is expected?
+        {
+        	PatientComment patientComment = new PatientComment();
+        	patientComment.setCreator( storedBy );
+        	patientComment.setCreatedDate( new Date() );
+        	patientComment.setCommentText( note.getValue() );    
+        	
+        	patientCommentService.addPatientComment( patientComment );
+        	
+        	programInstance.getPatientComments().add( patientComment );
+        	
+        	programInstanceService.updateProgramInstance( programInstance );
+        }    	
+    }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/Event.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/Event.java	2013-09-25 11:22:43 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/Event.java	2013-12-27 14:27:26 +0000
@@ -32,6 +32,7 @@
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+
 import org.hisp.dhis.common.BaseLinkableObject;
 import org.hisp.dhis.common.DxfNamespaces;
 
@@ -63,6 +64,8 @@
     private Coordinate coordinate;
 
     private List<DataValue> dataValues = new ArrayList<DataValue>();
+    
+    private List<Note> notes = new ArrayList<Note>();
 
     public Event()
     {
@@ -138,7 +141,7 @@
     public void setPerson( String person )
     {
         this.person = person;
-    }
+    }   	
 
     @JsonProperty( required = true )
     @JacksonXmlProperty( isAttribute = true )
@@ -188,6 +191,18 @@
     {
         this.dataValues = dataValues;
     }
+    
+    
+    @JsonProperty
+    @JacksonXmlElementWrapper( localName = "notes", namespace = DxfNamespaces.DXF_2_0 )
+    @JacksonXmlProperty( localName = "note", namespace = DxfNamespaces.DXF_2_0 )
+	public List<Note> getNotes() {
+		return notes;
+	}
+
+	public void setNotes(List<Note> notes) {
+		this.notes = notes;
+	}
 
     @Override
     public boolean equals( Object o )

=== added file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/Note.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/Note.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/Note.java	2013-12-27 14:27:26 +0000
@@ -0,0 +1,48 @@
+package org.hisp.dhis.dxf2.events.event;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+
+public class Note {
+
+	private String value;
+	
+	private String storedBy;
+	
+	private String storedDate;
+	
+	public Note()
+	{		
+	}
+	
+	@JsonProperty
+    @JacksonXmlProperty( isAttribute = true )
+	public String getValue() {
+		return value;
+	}
+
+	public void setValue(String value) {
+		this.value = value;
+	}
+
+	@JsonProperty
+    @JacksonXmlProperty( isAttribute = true )
+	public String getStoredBy() {
+		return storedBy;
+	}
+
+	public void setStoredBy(String storedBy) {
+		this.storedBy = storedBy;
+	}
+
+	@JsonProperty
+    @JacksonXmlProperty( isAttribute = true )
+	public String getStoredDate() {
+		return storedDate;
+	}
+
+	public void setStoredDate(String storedDate) {
+		this.storedDate = storedDate;
+	}	
+
+}

=== 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	2013-11-05 09:31:47 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/DefaultPatientAttributeService.java	2013-12-12 15:17:55 +0000
@@ -30,9 +30,12 @@
 
 import static org.hisp.dhis.i18n.I18nUtils.i18n;
 
+import java.util.ArrayList;
 import java.util.Collection;
 
 import org.hisp.dhis.i18n.I18nService;
+import org.hisp.dhis.program.Program;
+import org.hisp.dhis.program.ProgramService;
 import org.springframework.transaction.annotation.Transactional;
 
 /**
@@ -60,6 +63,13 @@
     {
         i18nService = service;
     }
+    
+    private ProgramService programService;
+    
+    public void setProgramService( ProgramService programService)
+    {
+    	this.programService = programService;
+    }
 
     // -------------------------------------------------------------------------
     // Implementation methods
@@ -129,5 +139,20 @@
     {
         return i18n( i18nService, patientAttributeStore.getByDisplayOnVisitSchedule( displayOnVisitSchedule ) );
     }
+
+	public Collection<PatientAttribute> getPatientAttributesWithoutProgram() {
+		
+		Collection<PatientAttribute> attributes = new ArrayList<PatientAttribute>();
+		Collection<Program> programs = new ArrayList<Program>();
+		
+		attributes = patientAttributeStore.getAll();
+		programs = programService.getAllPrograms();
+		
+		for( Program p : programs ){
+			attributes.removeAll( p.getPatientAttributes() );
+		}
+		
+		return i18n(i18nService, attributes);		
+	}
    
 }

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/startup/TableAlteror.java'
--- dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/startup/TableAlteror.java	2013-12-28 15:15:11 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/patient/startup/TableAlteror.java	2014-01-02 13:13:21 +0000
@@ -464,9 +464,12 @@
         {
             Statement statement = holder.getStatement();
 
-            ResultSet resultSet = statement.executeQuery( "SELECT gender FROM patient" );
-
-            if ( resultSet.next() )
+            ResultSet resultSet = statement.executeQuery( "SELECT gender FROM patientattribute" );
+            
+            //this should execute only if gender and other attributes
+            //mentioned below are not inserted. If gender is there, then we assume
+            //others are also inserted.
+            if ( !resultSet.next() )
             {
                 int max = jdbcTemplate.queryForObject( "select max(patientattributeid) from patientattribute", Integer.class );
 

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/DefaultProgramInstanceService.java'
--- dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/DefaultProgramInstanceService.java	2013-12-18 06:05:41 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/DefaultProgramInstanceService.java	2013-12-27 14:27:26 +0000
@@ -144,7 +144,7 @@
     // -------------------------------------------------------------------------
 
     public int addProgramInstance( ProgramInstance programInstance )
-    {
+    {    
         return programInstanceStore.save( programInstance );
     }
 
@@ -448,10 +448,13 @@
             }
         }
 
-        PatientComment patientComment = programInstance.getPatientComment();
-        if ( patientComment != null )
-        {
-            grid.addRow();
+        //Get patient comments for the program instance
+        
+        Set<PatientComment> patientComments = programInstance.getPatientComments();
+        
+        for( PatientComment patientComment : patientComments ){
+        	
+        	grid.addRow();
             grid.addValue( i18n.getString( "comment" ) + " " + i18n.getString( "on" ) + " "
                 + format.formatDateTime( patientComment.getCreatedDate() ) );
             grid.addValue( patientComment.getCommentText() );
@@ -816,19 +819,7 @@
                 grid.addRow();
                 grid.addValue( programStageInstance.getProgramStage().getReportDateDescription() );
                 grid.addValue( format.formatDate( programStageInstance.getExecutionDate() ) );
-            }
-
-            // Comments
-
-            PatientComment comment = programStageInstance.getPatientComment();
-
-            if ( comment != null )
-            {
-                grid.addRow();
-                grid.addValue( i18n.getString( "comment" ) + " " + i18n.getString( "on" ) + " "
-                    + format.formatDateTime( comment.getCreatedDate() ) );
-                grid.addValue( comment.getCommentText() );
-            }
+            }          
 
             // SMS messages
 

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/ProgramInstanceDeletionHandler.java'
--- dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/ProgramInstanceDeletionHandler.java	2013-11-04 03:49:17 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/ProgramInstanceDeletionHandler.java	2013-12-18 16:56:55 +0000
@@ -29,10 +29,13 @@
  */
 
 import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
 
 import org.hisp.dhis.patient.Patient;
+import org.hisp.dhis.patient.PatientAttribute;
+import org.hisp.dhis.patientattributevalue.PatientAttributeValue;
+import org.hisp.dhis.patientattributevalue.PatientAttributeValueService;
+import org.hisp.dhis.patientcomment.PatientComment;
+import org.hisp.dhis.patientcomment.PatientCommentService;
 import org.hisp.dhis.patientdatavalue.PatientDataValue;
 import org.hisp.dhis.patientdatavalue.PatientDataValueService;
 import org.hisp.dhis.system.deletion.DeletionHandler;
@@ -61,8 +64,22 @@
     {
         this.patientDataValueService = patientDataValueService;
     }
-
-    public ProgramStageDataElementService programStageDEService;
+    
+    private PatientCommentService patientCommentService;    
+
+    public void setPatientCommentService(PatientCommentService patientCommentService) 
+    {
+		this.patientCommentService = patientCommentService;
+	}
+    
+    private PatientAttributeValueService patientAttributeValueService;    
+
+	public void setPatientAttributeValueService( PatientAttributeValueService patientAttributeValueService )
+	{
+		this.patientAttributeValueService = patientAttributeValueService;
+	}
+
+	public ProgramStageDataElementService programStageDEService;
 
     public void setProgramStageDEService( ProgramStageDataElementService programStageDEService )
     {
@@ -89,53 +106,35 @@
     @Override
     public void deletePatient( Patient patient )
     {
-        Collection<ProgramInstance> programInstances = patient.getProgramInstances();
-
-        if ( programInstances != null )
-        {
-            // ---------------------------------------------------------------------
-            // Delete Patient data values
-            // ---------------------------------------------------------------------
-
-            for ( ProgramInstance programInstance : programInstances )
-            {
-                Set<PatientDataValue> dataValues = new HashSet<PatientDataValue>();
-
-                dataValues.addAll( patientDataValueService.getPatientDataValues( programInstance
-                    .getProgramStageInstances() ) );
-
-                if ( !dataValues.isEmpty() )
-                {
-                    for ( PatientDataValue dataValue : dataValues )
-                    {
-                        patientDataValueService.deletePatientDataValue( dataValue );
-                    }
-                }
-            }
-
-            // ---------------------------------------------------------------------
-            // Delete Program Stage Instances
-            // ---------------------------------------------------------------------
-
-            for ( ProgramInstance programInstance : programInstances )
-            {
-                Set<ProgramStageInstance> programStageInstances = programInstance.getProgramStageInstances();
-
-                for ( ProgramStageInstance programStageInstance : programStageInstances )
-                {
-                    programStageInstanceService.deleteProgramStageInstance( programStageInstance );
-                }
-            }
-
-            // ---------------------------------------------------------------------
-            // Delete Program Instances
-            // ---------------------------------------------------------------------
-
-            for ( ProgramInstance programInstance : programInstances )
-            {
-                programInstanceService.deleteProgramInstance( programInstance );
-            }
-        }
+    	for( ProgramInstance programInstance : patient.getProgramInstances() )
+    	{    		
+    		for( ProgramStageInstance programStageInstance : programInstance.getProgramStageInstances() )
+    		{
+    			for( PatientDataValue patientDataValue : patientDataValueService.getPatientDataValues(programStageInstance) )
+    			{        				
+    				patientDataValueService.deletePatientDataValue( patientDataValue );
+    			}
+    			
+     			programStageInstanceService.deleteProgramStageInstance( programStageInstance );        			
+    		}
+    		
+    		for ( PatientComment patientComment : programInstance.getPatientComments() )
+            {
+                patientCommentService.deletePatientComment(patientComment);
+            }
+    		
+    		for( PatientAttribute patientAttribute : programInstance.getProgram().getPatientAttributes() )
+    		{
+    			PatientAttributeValue patientAttributeValue = patientAttributeValueService.getPatientAttributeValue( patient, patientAttribute );
+        		
+        		if( patientAttributeValue != null )
+        		{
+        			patientAttributeValueService.deletePatientAttributeValue(patientAttributeValue);
+        		}
+    		}
+    		
+    		programInstanceService.deleteProgramInstance( programInstance );        		
+    	}
     }
 
     @Override

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-patient/src/main/resources/META-INF/dhis/beans.xml	2013-12-30 12:36:02 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/resources/META-INF/dhis/beans.xml	2014-01-02 11:35:24 +0000
@@ -262,6 +262,7 @@
 	<bean id="org.hisp.dhis.patient.PatientAttributeService" class="org.hisp.dhis.patient.DefaultPatientAttributeService">
 		<property name="patientAttributeStore" ref="org.hisp.dhis.patient.PatientAttributeStore" />
 		<property name="i18nService" ref="org.hisp.dhis.i18n.I18nService" />
+		<property name="programService" ref="org.hisp.dhis.program.ProgramService" />
 	</bean>
 
 	<bean
@@ -314,6 +315,10 @@
 		<property name="programInstanceService" ref="org.hisp.dhis.program.ProgramInstanceService" />
 		<property name="patientDataValueService"
 			ref="org.hisp.dhis.patientdatavalue.PatientDataValueService" />
+		<property name="patientCommentService"
+			ref="org.hisp.dhis.patientcomment.PatientCommentService" />
+		<property name="patientAttributeValueService"
+			ref="org.hisp.dhis.patientattributevalue.PatientAttributeValueService" />
 		<property name="programStageInstanceService"
 			ref="org.hisp.dhis.program.ProgramStageInstanceService" />
 	</bean>

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/resources/org/hisp/dhis/program/hibernate/ProgramInstance.hbm.xml'
--- dhis-2/dhis-services/dhis-service-patient/src/main/resources/org/hisp/dhis/program/hibernate/ProgramInstance.hbm.xml	2013-11-07 06:13:35 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/resources/org/hisp/dhis/program/hibernate/ProgramInstance.hbm.xml	2013-12-16 08:29:52 +0000
@@ -52,10 +52,11 @@
 			<many-to-many class="org.hisp.dhis.message.MessageConversation"
 				column="messageconversationid" />
 		</list>
-
-		<many-to-one name="patientComment" cascade="all"
-			class="org.hisp.dhis.patientcomment.PatientComment" column="patientcommentid"
-			foreign-key="fk_programinstance_patientcommentid" />
+		
+		<set name="patientComments" order-by="createdDate">
+			<key column="programinstanceid" />
+			<one-to-many class="org.hisp.dhis.patientcomment.PatientComment" />
+		</set>		
 
 	</class>
 </hibernate-mapping>

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/resources/org/hisp/dhis/program/hibernate/ProgramStageInstance.hbm.xml'
--- dhis-2/dhis-services/dhis-service-patient/src/main/resources/org/hisp/dhis/program/hibernate/ProgramStageInstance.hbm.xml	2013-12-05 10:41:52 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/resources/org/hisp/dhis/program/hibernate/ProgramStageInstance.hbm.xml	2013-12-16 08:29:52 +0000
@@ -57,10 +57,6 @@
 		<property name="completedUser" />
 
 		<property name="completedDate" />
-		
-		<many-to-one name="patientComment" cascade="all"
-			class="org.hisp.dhis.patientcomment.PatientComment" column="patientcommentid"
-			foreign-key="fk_programinstance_patientcommentid" />
-			
+					
 	</class>
 </hibernate-mapping>

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/event/PersonAttributeTypeController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/event/PersonAttributeTypeController.java	2013-09-27 10:43:38 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/event/PersonAttributeTypeController.java	2014-01-02 13:13:21 +0000
@@ -28,8 +28,18 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.hisp.dhis.api.controller.AbstractCrudController;
+import org.hisp.dhis.api.controller.WebMetaData;
+import org.hisp.dhis.api.controller.WebOptions;
+import org.hisp.dhis.common.Pager;
 import org.hisp.dhis.patient.PatientAttribute;
+import org.hisp.dhis.patient.PatientAttributeService;
+import org.hisp.dhis.program.Program;
+import org.hisp.dhis.program.ProgramService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 
@@ -41,4 +51,54 @@
 public class PersonAttributeTypeController extends AbstractCrudController<PatientAttribute>
 {
     public static final String RESOURCE_PATH = "/personAttributeTypes";
+    
+    @Autowired
+    private PatientAttributeService patientAttributeService;
+    
+    @Autowired
+    private ProgramService programService;
+    
+    
+    @Override
+    protected List<PatientAttribute> getEntityList( WebMetaData metaData, WebOptions options )
+    {
+        List<PatientAttribute> entityList = new ArrayList<PatientAttribute>();      
+
+        boolean withoutPrograms = options.getOptions().containsKey( "withoutPrograms" ) && Boolean.parseBoolean( options.getOptions().get( "withoutPrograms" ) );        
+
+        if ( withoutPrograms )
+        {
+        	entityList = new ArrayList<PatientAttribute>( patientAttributeService.getPatientAttributesWithoutProgram() );
+        }
+        
+        else if ( options.getOptions().containsKey( "program" ) )
+        {
+            String programId = options.getOptions().get( "program" );
+            Program program = programService.getProgram( programId );
+
+            if ( program != null )
+            {
+                entityList = new ArrayList<PatientAttribute>( program.getPatientAttributes() );
+            }
+        }
+        
+        else if ( options.hasPaging() )
+        {
+            int count = manager.getCount( getEntityClass() );
+
+            Pager pager = new Pager( options.getPage(), count, options.getPageSize() );
+            metaData.setPager( pager );
+
+            entityList = new ArrayList<PatientAttribute>( manager.getBetween( getEntityClass(), pager.getOffset(), pager.getPageSize() ) );
+        }
+        
+        else
+        {
+            entityList = new ArrayList<PatientAttribute>( patientAttributeService.getAllPatientAttributes() );
+        }
+
+        return entityList;      
+        
+    }
+    
 }

=== modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/caseentry/SaveProgramInstanceCommentAction.java'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/caseentry/SaveProgramInstanceCommentAction.java	2013-08-23 16:05:01 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/caseentry/SaveProgramInstanceCommentAction.java	2013-12-16 08:29:52 +0000
@@ -93,14 +93,9 @@
         {
             PatientComment patientComment = new PatientComment( comment, currentUserService.getCurrentUsername(),
                 new Date() );
-            programInstance.setPatientComment( patientComment );
-            programInstanceService.updateProgramInstance( programInstance );
-        }
-        else if ( programInstance.getPatientComment() != null )
-        {
-            programInstance.setPatientComment( null );
-            programInstanceService.updateProgramInstance( programInstance );
-        }
+            programInstance.getPatientComments().add(patientComment);
+            programInstanceService.updateProgramInstance( programInstance );
+        }      
 
         return SUCCESS;
     }

=== modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/reminder/SavePatientCommentAction.java'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/reminder/SavePatientCommentAction.java	2013-10-09 14:43:56 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/java/org/hisp/dhis/caseentry/action/reminder/SavePatientCommentAction.java	2013-12-16 17:16:30 +0000
@@ -37,6 +37,9 @@
 import org.hisp.dhis.user.CurrentUserService;
 
 import com.opensymphony.xwork2.Action;
+import java.util.Set;
+import org.hisp.dhis.program.ProgramInstance;
+import org.hisp.dhis.program.ProgramInstanceService;
 
 /**
  * @author Chau Thu Tran
@@ -56,6 +59,13 @@
     {
         this.programStageInstanceService = programStageInstanceService;
     }
+    
+    private ProgramInstanceService programInstanceService;
+
+    public void setProgramInstanceService( ProgramInstanceService programInstanceService )
+    {
+        this.programInstanceService = programInstanceService;
+    }
 
     private CurrentUserService currentUserService;
 
@@ -96,28 +106,26 @@
     public String execute()
     {
         ProgramStageInstance programStageInstance = programStageInstanceService
-            .getProgramStageInstance( programStageInstanceId );
-
-        PatientComment patientComment = programStageInstance.getPatientComment();
+            .getProgramStageInstance( programStageInstanceId );  
+        
+        ProgramInstance programInstance = programStageInstance.getProgramInstance();
+        
+        
+        Set<PatientComment> patientComments = programInstance.getPatientComments();
 
         if ( commentText != null && !commentText.isEmpty() )
         {
-            if ( patientComment == null )
-            {
-                patientComment = new PatientComment();
-            }
+            PatientComment patientComment = new PatientComment();       
 
             patientComment.setCommentText( commentText );
             patientComment.setCreator( currentUserService.getCurrentUsername() );
             patientComment.setCreatedDate( new Date() );
-            programStageInstance.setPatientComment( patientComment );
-        }
-        else if ( patientComment != null )
-        {
-            patientCommentService.deletePatientComment( patientComment );
-        }
-
-        programStageInstanceService.updateProgramStageInstance( programStageInstance );
+            patientComments.add(patientComment);
+            
+            programInstanceService.updateProgramInstance( programInstance );           
+            
+        }        
+        
         return SUCCESS;
     }
 

=== modified file 'dhis-2/dhis-web/dhis-web-caseentry/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-caseentry/src/main/resources/META-INF/dhis/beans.xml	2013-12-18 08:01:59 +0000
+++ dhis-2/dhis-web/dhis-web-caseentry/src/main/resources/META-INF/dhis/beans.xml	2013-12-27 14:27:26 +0000
@@ -475,7 +475,7 @@
 
 	<bean id="org.hisp.dhis.caseentry.action.patient.RemovePatientAction"
 		class="org.hisp.dhis.caseentry.action.patient.RemovePatientAction"
-		scope="prototype">
+		scope="prototype">		
 		<property name="patientService" ref="org.hisp.dhis.patient.PatientService" />
 	</bean>
 
@@ -1031,6 +1031,8 @@
 		scope="prototype">
 		<property name="programStageInstanceService"
 			ref="org.hisp.dhis.program.ProgramStageInstanceService" />
+                <property name="programInstanceService"
+			ref="org.hisp.dhis.program.ProgramInstanceService" />
 		<property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService" />
 		<property name="patientCommentService"
 			ref="org.hisp.dhis.patientcomment.PatientCommentService" />