← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 16991: import/export of csv, wip

 

------------------------------------------------------------
revno: 16991
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Wed 2014-10-08 12:11:14 +0700
message:
  import/export of csv, wip
modified:
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/csv/CsvEventDataValue.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/csv/CsvEventUtils.java
  dhis-2/dhis-services/dhis-service-tracker/src/main/resources/org/hisp/dhis/program/hibernate/ProgramStageInstance.hbm.xml
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EventController.java


--
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-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/csv/CsvEventDataValue.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/csv/CsvEventDataValue.java	2014-10-07 06:35:04 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/csv/CsvEventDataValue.java	2014-10-08 05:11:14 +0000
@@ -30,52 +30,34 @@
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonPropertyOrder;
-import org.hisp.dhis.event.EventStatus;
 import org.springframework.util.Assert;
 
+import java.util.Objects;
+
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
  */
 @JsonPropertyOrder( {
     "event",
     "status",
-    "program",
-    "programInstance",
-    "programStage",
     "enrollment",
-    "enrollmentStatus",
-    "orgUnit",
-    "trackedEntityInstance",
     "eventDate",
     "dueDate",
     "latitude",
     "longitude",
-    "followUp",
     "dataElement",
     "value",
-    "providedElsewhere",
-    "storedBy"
+    "storedBy",
+    "providedElsewhere"
 } )
 public class CsvEventDataValue
 {
     private String event;
 
-    private EventStatus status = EventStatus.ACTIVE;
-
-    private String program;
-
-    private String programInstance;
-
-    private String programStage;
+    private String status;
 
     private String enrollment;
 
-    private EventStatus enrollmentStatus;
-
-    private String orgUnit;
-
-    private String trackedEntityInstance;
-
     private String eventDate;
 
     private String dueDate;
@@ -84,16 +66,14 @@
 
     private Double longitude;
 
-    private Boolean followup;
-
     private String dataElement;
 
     private String value;
 
-    private Boolean providedElsewhere = false;
-
     private String storedBy;
 
+    private Boolean providedElsewhere;
+
     public CsvEventDataValue()
     {
     }
@@ -104,22 +84,15 @@
 
         this.event = dataValue.getEvent();
         this.status = dataValue.getStatus();
-        this.program = dataValue.getProgram();
-        this.programInstance = dataValue.getProgramInstance();
-        this.programStage = dataValue.getProgramStage();
         this.enrollment = dataValue.getEnrollment();
-        this.enrollmentStatus = dataValue.getEnrollmentStatus();
-        this.orgUnit = dataValue.getOrgUnit();
-        this.trackedEntityInstance = dataValue.getTrackedEntityInstance();
         this.eventDate = dataValue.getEventDate();
         this.dueDate = dataValue.getDueDate();
         this.latitude = dataValue.getLatitude();
         this.longitude = dataValue.getLongitude();
-        this.followup = dataValue.getFollowup();
         this.dataElement = dataValue.getDataElement();
         this.value = dataValue.getValue();
+        this.storedBy = dataValue.getStoredBy();
         this.providedElsewhere = dataValue.getProvidedElsewhere();
-        this.storedBy = dataValue.getStoredBy();
     }
 
     @JsonProperty
@@ -134,50 +107,17 @@
     }
 
     @JsonProperty
-    public EventStatus getStatus()
+    public String getStatus()
     {
         return status;
     }
 
-    public void setStatus( EventStatus status )
+    public void setStatus( String status )
     {
         this.status = status;
     }
 
     @JsonProperty
-    public String getProgram()
-    {
-        return program;
-    }
-
-    public void setProgram( String program )
-    {
-        this.program = program;
-    }
-
-    @JsonProperty
-    public String getProgramInstance()
-    {
-        return programInstance;
-    }
-
-    public void setProgramInstance( String programInstance )
-    {
-        this.programInstance = programInstance;
-    }
-
-    @JsonProperty
-    public String getProgramStage()
-    {
-        return programStage;
-    }
-
-    public void setProgramStage( String programStage )
-    {
-        this.programStage = programStage;
-    }
-
-    @JsonProperty
     public String getEnrollment()
     {
         return enrollment;
@@ -189,39 +129,6 @@
     }
 
     @JsonProperty
-    public EventStatus getEnrollmentStatus()
-    {
-        return enrollmentStatus;
-    }
-
-    public void setEnrollmentStatus( EventStatus enrollmentStatus )
-    {
-        this.enrollmentStatus = enrollmentStatus;
-    }
-
-    @JsonProperty
-    public String getOrgUnit()
-    {
-        return orgUnit;
-    }
-
-    public void setOrgUnit( String orgUnit )
-    {
-        this.orgUnit = orgUnit;
-    }
-
-    @JsonProperty
-    public String getTrackedEntityInstance()
-    {
-        return trackedEntityInstance;
-    }
-
-    public void setTrackedEntityInstance( String trackedEntityInstance )
-    {
-        this.trackedEntityInstance = trackedEntityInstance;
-    }
-
-    @JsonProperty
     public String getEventDate()
     {
         return eventDate;
@@ -266,17 +173,6 @@
     }
 
     @JsonProperty
-    public Boolean getFollowup()
-    {
-        return followup;
-    }
-
-    public void setFollowup( Boolean followup )
-    {
-        this.followup = followup;
-    }
-
-    @JsonProperty
     public String getDataElement()
     {
         return dataElement;
@@ -319,4 +215,55 @@
     {
         this.storedBy = storedBy;
     }
+
+    @Override
+    public int hashCode()
+    {
+        return Objects.hash( event, status, enrollment, eventDate, dueDate, latitude, longitude, dataElement, value, providedElsewhere, storedBy );
+    }
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
+        {
+            return true;
+        }
+        if ( obj == null || getClass() != obj.getClass() )
+        {
+            return false;
+        }
+
+        final CsvEventDataValue other = (CsvEventDataValue) obj;
+
+        return Objects.equals( this.event, other.event )
+            && Objects.equals( this.status, other.status )
+            && Objects.equals( this.enrollment, other.enrollment )
+            && Objects.equals( this.eventDate, other.eventDate )
+            && Objects.equals( this.dueDate, other.dueDate )
+            && Objects.equals( this.latitude, other.latitude )
+            && Objects.equals( this.longitude, other.longitude )
+            && Objects.equals( this.dataElement, other.dataElement )
+            && Objects.equals( this.value, other.value )
+            && Objects.equals( this.storedBy, other.storedBy )
+            && Objects.equals( this.providedElsewhere, other.providedElsewhere );
+    }
+
+    @Override
+    public String toString()
+    {
+        return com.google.common.base.Objects.toStringHelper( this )
+            .add( "event", event )
+            .add( "status", status )
+            .add( "enrollment", enrollment )
+            .add( "eventDate", eventDate )
+            .add( "dueDate", dueDate )
+            .add( "latitude", latitude )
+            .add( "longitude", longitude )
+            .add( "dataElement", dataElement )
+            .add( "value", value )
+            .add( "storedBy", storedBy )
+            .add( "providedElsewhere", providedElsewhere )
+            .toString();
+    }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/csv/CsvEventUtils.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/csv/CsvEventUtils.java	2014-10-07 06:35:04 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/events/event/csv/CsvEventUtils.java	2014-10-08 05:11:14 +0000
@@ -28,14 +28,21 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import com.fasterxml.jackson.databind.MappingIterator;
+import com.fasterxml.jackson.databind.ObjectReader;
 import com.fasterxml.jackson.databind.ObjectWriter;
 import com.fasterxml.jackson.dataformat.csv.CsvMapper;
+import com.fasterxml.jackson.dataformat.csv.CsvParser;
 import com.fasterxml.jackson.dataformat.csv.CsvSchema;
+import org.hisp.dhis.dxf2.events.event.Coordinate;
 import org.hisp.dhis.dxf2.events.event.DataValue;
 import org.hisp.dhis.dxf2.events.event.Event;
 import org.hisp.dhis.dxf2.events.event.Events;
+import org.hisp.dhis.event.EventStatus;
+import org.springframework.util.StringUtils;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.List;
@@ -47,7 +54,12 @@
 {
     private static CsvMapper csvMapper = new CsvMapper();
 
-    private static CsvSchema csvSchema = csvMapper.schemaFor( CsvEventDataValue.class );
+    private static CsvSchema csvSchema = csvMapper.schemaFor( CsvEventDataValue.class ).withLineSeparator( "\n" );
+
+    static
+    {
+        csvMapper.enable( CsvParser.Feature.WRAP_AS_ARRAY );
+    }
 
     public static CsvMapper getCsvMapper()
     {
@@ -59,9 +71,9 @@
         return csvSchema;
     }
 
-    public static void writeEvents( OutputStream outputStream, Events events, boolean withHeaders ) throws IOException
+    public static void writeEvents( OutputStream outputStream, Events events, boolean withHeader ) throws IOException
     {
-        ObjectWriter writer = getCsvMapper().writer( getCsvSchema().withUseHeader( withHeaders ) );
+        ObjectWriter writer = getCsvMapper().writer( getCsvSchema().withUseHeader( withHeader ) );
 
         List<CsvEventDataValue> dataValues = new ArrayList<>();
 
@@ -69,13 +81,8 @@
         {
             CsvEventDataValue templateDataValue = new CsvEventDataValue();
             templateDataValue.setEvent( event.getEvent() );
-            templateDataValue.setProgram( event.getProgram() == null ? events.getProgram() : event.getProgram() );
-            templateDataValue.setProgramInstance( events.getProgramInstance() );
-            templateDataValue.setProgramStage( event.getProgramStage() );
+            templateDataValue.setStatus( event.getStatus() != null ? event.getStatus().name() : null );
             templateDataValue.setEnrollment( event.getEnrollment() );
-            templateDataValue.setEnrollmentStatus( event.getEnrollmentStatus() );
-            templateDataValue.setOrgUnit( event.getOrgUnit() );
-            templateDataValue.setTrackedEntityInstance( event.getTrackedEntityInstance() );
             templateDataValue.setEventDate( event.getEventDate() );
             templateDataValue.setDueDate( event.getDueDate() );
             templateDataValue.setStoredBy( event.getStoredBy() );
@@ -86,8 +93,6 @@
                 templateDataValue.setLongitude( event.getCoordinate().getLongitude() );
             }
 
-            templateDataValue.setFollowup( event.getFollowup() );
-
             for ( DataValue value : event.getDataValues() )
             {
                 CsvEventDataValue dataValue = new CsvEventDataValue( templateDataValue );
@@ -107,6 +112,48 @@
         writer.writeValue( outputStream, dataValues );
     }
 
+    public static Events readEvents( InputStream inputStream, boolean skipFirst ) throws IOException
+    {
+        Events events = new Events();
+
+        ObjectReader reader = getCsvMapper()
+            .reader( CsvEventDataValue.class ).with( getCsvSchema().withSkipFirstDataRow( skipFirst ) );
+
+        MappingIterator<CsvEventDataValue> iterator = reader.readValues( inputStream );
+        Event event = new Event();
+        event.setEvent( "not_valid" );
+
+        while ( iterator.hasNext() )
+        {
+            CsvEventDataValue dataValue = iterator.next();
+
+            if ( !event.getEvent().equals( dataValue.getEvent() ) )
+            {
+                event = new Event();
+                event.setEvent( dataValue.getEvent() );
+                event.setStatus( StringUtils.isEmpty( dataValue.getStatus() ) ? EventStatus.ACTIVE : Enum.valueOf( EventStatus.class, dataValue.getStatus() ) );
+                event.setEnrollment( dataValue.getEnrollment() );
+                event.setEventDate( event.getEventDate() );
+                event.setDueDate( event.getDueDate() );
+
+                if ( dataValue.getLongitude() != null && dataValue.getLatitude() != null )
+                {
+                    event.setCoordinate( new Coordinate( dataValue.getLongitude(), dataValue.getLatitude() ) );
+                }
+
+                events.getEvents().add( event );
+            }
+
+            DataValue value = new DataValue( dataValue.getDataElement(), dataValue.getValue() );
+            value.setStoredBy( dataValue.getStoredBy() );
+            value.setProvidedElsewhere( dataValue.getProvidedElsewhere() );
+
+            event.getDataValues().add( value );
+        }
+
+        return events;
+    }
+
     private CsvEventUtils()
     {
     }

=== modified file 'dhis-2/dhis-services/dhis-service-tracker/src/main/resources/org/hisp/dhis/program/hibernate/ProgramStageInstance.hbm.xml'
--- dhis-2/dhis-services/dhis-service-tracker/src/main/resources/org/hisp/dhis/program/hibernate/ProgramStageInstance.hbm.xml	2014-06-27 10:55:57 +0000
+++ dhis-2/dhis-services/dhis-service-tracker/src/main/resources/org/hisp/dhis/program/hibernate/ProgramStageInstance.hbm.xml	2014-10-08 05:11:14 +0000
@@ -4,64 +4,64 @@
   "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd";>
 
 <hibernate-mapping>
-	<class name="org.hisp.dhis.program.ProgramStageInstance" table="programstageinstance">
-
-		<id name="id" column="programstageinstanceid">
-			<generator class="native" />
-		</id>
-
-		<property name="uid" column="uid" unique="true" length="11" />
-
-		<property name="created" type="timestamp" />
-
-		<property name="lastUpdated" type="timestamp" />
-
-		<many-to-one name="programInstance" class="org.hisp.dhis.program.ProgramInstance"
-			column="programinstanceid" not-null="true" foreign-key="fk_programstageinstance_programinstanceid" />
-
-		<many-to-one name="programStage" class="org.hisp.dhis.program.ProgramStage"
-			column="programstageid" not-null="true"	foreign-key="fk_programstageinstance_programstageid" />
-
-		<property name="dueDate" column="duedate" />
-
-		<property name="executionDate" column="executiondate" type="timestamp" />
-
-		<many-to-one name="organisationUnit"
-			class="org.hisp.dhis.organisationunit.OrganisationUnit" column="organisationunitid"
-			foreign-key="fk_programstageinstance_organisationunitid" />
-
-		<list name="outboundSms" table="programstageinstance_outboundsms">
-			<key column="programstageinstanceid" />
-			<list-index column="sort_order" base="1" />
-			<many-to-many class="org.hisp.dhis.sms.outbound.OutboundSms"
-				column="outboundsmsid" />
-		</list>
-
-		<list name="messageConversations" table="programstageinstance_messageconversation">
-			<key column="programstageinstanceid" />
-			<list-index column="sort_order" base="1" />
-			<many-to-many class="org.hisp.dhis.message.MessageConversation"
-				column="messageconversationid" />
-		</list>
-
- 		<property name="status" column="status" type="org.hisp.dhis.program.EventStatusUserType" not-null="true" />
- 
-		<property name="longitude" />
-
-		<property name="latitude" />
-
-		<property name="completedUser" />
-
-		<property name="completedDate" />
-
-		<list name="comments" table="programstageinstancecomments" cascade="all"> 
-            <key column="programstageinstanceid"/>
-            <list-index column="sort_order" base="1" />
-            <many-to-many column="trackedentitycommentid" unique="true" class="org.hisp.dhis.trackedentitycomment.TrackedEntityComment"/>
-        </list>
-		
-		<!--<many-to-one name="comment" cascade="all" class="org.hisp.dhis.trackedentitycomment.TrackedEntityComment" 
-		    column="trackedentitycommentid" foreign-key="fk_programinstance_commentid" />-->
-
-	</class>
+  <class name="org.hisp.dhis.program.ProgramStageInstance" table="programstageinstance">
+
+    <id name="id" column="programstageinstanceid">
+      <generator class="native" />
+    </id>
+
+    <property name="uid" column="uid" unique="true" length="11" />
+
+    <property name="created" type="timestamp" />
+
+    <property name="lastUpdated" type="timestamp" />
+
+    <many-to-one name="programInstance" class="org.hisp.dhis.program.ProgramInstance"
+      column="programinstanceid" not-null="true" foreign-key="fk_programstageinstance_programinstanceid" />
+
+    <many-to-one name="programStage" class="org.hisp.dhis.program.ProgramStage"
+      column="programstageid" not-null="true" foreign-key="fk_programstageinstance_programstageid" />
+
+    <property name="dueDate" column="duedate" />
+
+    <property name="executionDate" column="executiondate" type="timestamp" />
+
+    <many-to-one name="organisationUnit"
+      class="org.hisp.dhis.organisationunit.OrganisationUnit" column="organisationunitid"
+      foreign-key="fk_programstageinstance_organisationunitid" />
+
+    <list name="outboundSms" table="programstageinstance_outboundsms">
+      <key column="programstageinstanceid" />
+      <list-index column="sort_order" base="1" />
+      <many-to-many class="org.hisp.dhis.sms.outbound.OutboundSms"
+        column="outboundsmsid" />
+    </list>
+
+    <list name="messageConversations" table="programstageinstance_messageconversation">
+      <key column="programstageinstanceid" />
+      <list-index column="sort_order" base="1" />
+      <many-to-many class="org.hisp.dhis.message.MessageConversation"
+        column="messageconversationid" />
+    </list>
+
+    <property name="status" column="status" type="org.hisp.dhis.program.EventStatusUserType" not-null="true" />
+
+    <property name="longitude" />
+
+    <property name="latitude" />
+
+    <property name="completedUser" />
+
+    <property name="completedDate" />
+
+    <list name="comments" table="programstageinstancecomments" cascade="all">
+      <key column="programstageinstanceid" />
+      <list-index column="sort_order" base="1" />
+      <many-to-many column="trackedentitycommentid" unique="true" class="org.hisp.dhis.trackedentitycomment.TrackedEntityComment" />
+    </list>
+
+    <!--<many-to-one name="comment" cascade="all" class="org.hisp.dhis.trackedentitycomment.TrackedEntityComment"
+        column="trackedentitycommentid" foreign-key="fk_programinstance_commentid" />-->
+
+  </class>
 </hibernate-mapping>

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EventController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EventController.java	2014-10-07 06:35:04 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/EventController.java	2014-10-08 05:11:14 +0000
@@ -139,7 +139,7 @@
         @RequestParam( required = false ) @DateTimeFormat( pattern = "yyyy-MM-dd" ) Date startDate,
         @RequestParam( required = false ) @DateTimeFormat( pattern = "yyyy-MM-dd" ) Date endDate,
         @RequestParam( required = false ) EventStatus status,
-        @RequestParam( required = false, defaultValue = "true") boolean withHeaders,
+        @RequestParam( required = false, defaultValue = "false" ) boolean skipHeader,
         @RequestParam Map<String, String> parameters, Model model, HttpServletResponse response, HttpServletRequest request ) throws IOException
     {
         WebOptions options = new WebOptions( parameters );
@@ -198,7 +198,7 @@
             events.setEvents( PagerUtils.pageCollection( events.getEvents(), pager ) );
         }
 
-        CsvEventUtils.writeEvents( response.getOutputStream(), events, withHeaders );
+        CsvEventUtils.writeEvents( response.getOutputStream(), events, !skipHeader );
     }
 
     @RequestMapping( value = "", method = RequestMethod.GET )
@@ -485,6 +485,16 @@
         }
     }
 
+
+    @RequestMapping( method = RequestMethod.POST, consumes = { "application/csv", "text/csv" } )
+    @PreAuthorize( "hasRole('ALL') or hasRole('F_TRACKED_ENTITY_DATAVALUE_ADD')" )
+    public void postCsvEvents(
+        @RequestParam( required = false, defaultValue = "false" ) boolean skipFirst,
+        HttpServletResponse response, HttpServletRequest request, ImportOptions importOptions ) throws IOException
+    {
+        CsvEventUtils.readEvents( request.getInputStream(), skipFirst );
+    }
+
     // -------------------------------------------------------------------------
     // UPDATE
     // -------------------------------------------------------------------------