SI-3095 Schnittstelle SARIS
diff --git a/SAMO-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/samointerface/dtos/ForeignFailureDataDto.java b/SAMO-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/samointerface/dtos/ForeignFailureDataDto.java
index fb596bf..0733732 100644
--- a/SAMO-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/samointerface/dtos/ForeignFailureDataDto.java
+++ b/SAMO-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/samointerface/dtos/ForeignFailureDataDto.java
@@ -30,6 +30,14 @@
 @Data
 public class ForeignFailureDataDto implements Serializable {
 
+    private boolean isAutopublish;
+
+    private boolean isOnceOnlyImport;
+
+    private boolean isExcludeEquals;
+
+    private boolean isExcludeAlreadyEdited;
+
     @NotNull
     private boolean isPlanned;
 
diff --git a/SAMO-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/samointerface/service/ImportService.java b/SAMO-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/samointerface/service/ImportService.java
index e652684..b8a7acf 100644
--- a/SAMO-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/samointerface/service/ImportService.java
+++ b/SAMO-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/samointerface/service/ImportService.java
@@ -24,6 +24,7 @@
 import org.eclipse.openk.gridfailureinformation.samointerface.exceptions.InternalServerErrorException;
 import org.eclipse.openk.gridfailureinformation.samointerface.mapper.SAMOMapper;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.messaging.MessageChannel;
@@ -45,6 +46,15 @@
     @Autowired
     SAMOMapper samoMapper;
 
+    @Value("${gridFailureInformation.autopublish:false}")
+    private boolean autopublish;
+    @Value("${gridFailureInformation.onceOnlyImport:false}")
+    private boolean onceOnlyImport;
+    @Value("${gridFailureInformation.excludeEquals:true}")
+    private boolean excludeEquals;
+    @Value("${gridFailureInformation.excludeAlreadyEdited:true}")
+    private boolean excludeAlreadyEdited;
+
     public void importSAMOOutage(String samoOutageJson) {
         try {
             SAMOOutage samoOutage = objectMapper.readValue(samoOutageJson, SAMOOutage.class);
@@ -69,6 +79,10 @@
 
     private ForeignFailureDataDto createForeignFailureData(SAMOOutage samoOutage) {
         ForeignFailureDataDto foreignFailureDataDto = samoMapper.toForeignFailureDataDto(samoOutage);
+        foreignFailureDataDto.setAutopublish(autopublish);
+        foreignFailureDataDto.setOnceOnlyImport(onceOnlyImport);
+        foreignFailureDataDto.setExcludeEquals(excludeEquals);
+        foreignFailureDataDto.setExcludeAlreadyEdited(excludeAlreadyEdited);
         foreignFailureDataDto.setBranch(Constants.BRANCH_ELECTRICITY); //fixme klärung: logik einbauen
         foreignFailureDataDto.setPlanned(false); //fixme klärung
         return foreignFailureDataDto;
diff --git a/SAMO-Interface/src/main/resources/application.yml b/SAMO-Interface/src/main/resources/application.yml
index 824c904..fba97c3 100644
--- a/SAMO-Interface/src/main/resources/application.yml
+++ b/SAMO-Interface/src/main/resources/application.yml
@@ -46,6 +46,12 @@
   directory: /opt/transfer/SAMOInterfaceDEVsftpTest/
   fileFilter: '*.json'
   cron: 0/10 * * ? * * # Check for new file in directory every 'cron' time
+  
+gridFailureInformation:
+  autopublish: false
+  onceOnlyImport: false
+  excludeEquals: true
+  excludeAlreadyEdited: false
 ---
 
 spring:
diff --git a/SAMO-Interface/src/main/resources/application_localdev.yml b/SAMO-Interface/src/main/resources/application_localdev.yml
index cc1bc56..35c8064 100644
--- a/SAMO-Interface/src/main/resources/application_localdev.yml
+++ b/SAMO-Interface/src/main/resources/application_localdev.yml
@@ -36,7 +36,10 @@
       tracking-modes: cookie
 
 gridFailureInformation:
-  maxListSize: 2000
+  autopublish: false
+  onceOnlyImport: false
+  excludeEquals: true
+  excludeAlreadyEdited: true
 
 logging.level.org.eclipse.openk.gridfailureinformation.jobs.stoerauskunftinterface.api.StoerauskunftApi: DEBUG
 
diff --git a/SARIS-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/sarisinterface/controller/ImportController.java b/SARIS-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/sarisinterface/controller/ImportController.java
index 8ad134d..bb064ac 100644
--- a/SARIS-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/sarisinterface/controller/ImportController.java
+++ b/SARIS-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/sarisinterface/controller/ImportController.java
@@ -53,8 +53,8 @@
     @ResponseStatus(HttpStatus.OK)
     public void importUserNotification() {
       importService.importForeignFailures(Constants.SARIS_ELECTRICITY_BRANCH_ID);
-      importService.importForeignFailures(Constants.SARIS_GAS_BRANCH_ID);
-      importService.importForeignFailures(Constants.SARIS_WATER_BRANCH_ID);
+      /*importService.importForeignFailures(Constants.SARIS_GAS_BRANCH_ID);
+      importService.importForeignFailures(Constants.SARIS_WATER_BRANCH_ID);*/
     }
 
     @GetMapping("/response-test")
diff --git a/SARIS-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/sarisinterface/dtos/ForeignFailureDataDto.java b/SARIS-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/sarisinterface/dtos/ForeignFailureDataDto.java
index 4f4b79e..2202cbf 100644
--- a/SARIS-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/sarisinterface/dtos/ForeignFailureDataDto.java
+++ b/SARIS-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/sarisinterface/dtos/ForeignFailureDataDto.java
@@ -32,6 +32,12 @@
 
     private boolean isAutopublish;
 
+    private boolean isOnceOnlyImport;
+
+    private boolean isExcludeEquals;
+
+    private boolean isExcludeAlreadyEdited;
+
     @NotNull
     private boolean isPlanned;
 
diff --git a/SARIS-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/sarisinterface/service/ImportService.java b/SARIS-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/sarisinterface/service/ImportService.java
index 67a3f7e..a77ce54 100644
--- a/SARIS-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/sarisinterface/service/ImportService.java
+++ b/SARIS-Interface/src/main/java/org/eclipse/openk/gridfailureinformation/sarisinterface/service/ImportService.java
@@ -59,12 +59,18 @@
 
     @Value("${gridFailureInformation.autopublish:false}")
     private boolean autopublish;
+    @Value("${gridFailureInformation.onceOnlyImport:false}")
+    private boolean onceOnlyImport;
+    @Value("${gridFailureInformation.excludeEquals:true}")
+    private boolean excludeEquals;
+    @Value("${gridFailureInformation.excludeAlreadyEdited:true}")
+    private boolean excludeAlreadyEdited;
 
     public void importForeignFailures(int sarisSparteId) {
 
-        GetAktuelleGVUsInfoAllgemeinResponse sarisResponse = sarisWebservice.getAktuelleGVU(sarisSparteId, false);
+//        GetAktuelleGVUsInfoAllgemeinResponse sarisResponse = sarisWebservice.getAktuelleGVU(sarisSparteId, false);
 
-//        GetAktuelleGVUsInfoAllgemeinResponse sarisResponse = getMockedSarisResponse("sarisRealMockResponse.xml");
+        GetAktuelleGVUsInfoAllgemeinResponse sarisResponse = getMockedSarisResponse("sarisRealMockResponse.xml");
 
         ArrayOfViewGeplanteVU getAktuelleGVUsInfoAllgemeinResult =
                 sarisResponse.getGetAktuelleGVUsInfoAllgemeinResult();
@@ -110,6 +116,9 @@
         ForeignFailureDataDto foreignFailureDataDto = sarisMapper.toForeignFailureDataDto(viewGeplanteVU);
         foreignFailureDataDto.setPlanned(true);
         foreignFailureDataDto.setAutopublish(autopublish);
+        foreignFailureDataDto.setOnceOnlyImport(onceOnlyImport);
+        foreignFailureDataDto.setExcludeEquals(excludeEquals);
+        foreignFailureDataDto.setExcludeAlreadyEdited(excludeAlreadyEdited);
         return foreignFailureDataDto;
     }
 
diff --git a/SARIS-Interface/src/main/resources/application.yml b/SARIS-Interface/src/main/resources/application.yml
index a3eef9e..566947e 100644
--- a/SARIS-Interface/src/main/resources/application.yml
+++ b/SARIS-Interface/src/main/resources/application.yml
@@ -53,10 +53,11 @@
     month: 2
     year: 2020
     
-    
-    
 gridFailureInformation:
   autopublish: false
+  onceOnlyImport: false
+  excludeEquals: true
+  excludeAlreadyEdited: true
 
 security.endpoint:
   user: ${GFI_MANUAL_ENDPOINTS_USERNAME}
diff --git a/SARIS-Interface/src/main/resources/application_localdev.yml b/SARIS-Interface/src/main/resources/application_localdev.yml
index 221bef8..3eb7c08 100644
--- a/SARIS-Interface/src/main/resources/application_localdev.yml
+++ b/SARIS-Interface/src/main/resources/application_localdev.yml
@@ -55,9 +55,14 @@
   scheduling-import:
     enabled: false
     cron: 0 */15 * ? * *
+  testIntegration:
+    day: 11
+    month: 2
+    year: 2020
     
 gridFailureInformation:
   autopublish: false
+  onceOnlyImport: false
 
 security.endpoint:
   user: ${GFI_MANUAL_ENDPOINTS_USERNAME}
@@ -78,6 +83,10 @@
 #    importkey: sitImportExchange.failureImportKey_localdev_simon
 
     # Importkanal
-    importExchange: sitImportExchange
-    importQueue: sitImportQueue
-    importkey: sitImportExchange.failureImportKey
+#    importExchange: sitImportExchange
+#    importQueue: sitImportQueue
+#    importkey: sitImportExchange.failureImportKey
+
+    importExchange: sitImportExchange_localdev
+    importQueue: sitImportQueue_localdev
+    importkey: sitImportExchange.failureImportKey_localdev
\ No newline at end of file
diff --git a/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/service/ImportService.java b/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/service/ImportService.java
index 98cfb1e..346ae91 100644
--- a/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/service/ImportService.java
+++ b/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/service/ImportService.java
@@ -14,7 +14,10 @@
  */
 package org.eclipse.openk.gridfailureinformation.service;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang.SerializationUtils;
 import org.apache.commons.lang.StringUtils;
 import org.eclipse.openk.gridfailureinformation.bpmn.impl.GfiProcessState;
 import org.eclipse.openk.gridfailureinformation.bpmn.impl.tasks.ProcessHelper;
@@ -37,6 +40,7 @@
 import java.math.BigDecimal;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.UUID;
 
@@ -72,6 +76,9 @@
     @Autowired
     ProcessHelper processHelper;
 
+    @Autowired
+    ObjectMapper objectMapper;
+
     public boolean validateAndImport(ImportDataDto importDataDto) {
         ForeignFailureDataDto foreignFailureDataDto = importDataValidator.readSafeForeignFailureInfo(importDataDto);
 
@@ -107,7 +114,8 @@
             }
 
             FailureInformationDto retVal = failureInformationService.insertFailureInfo(failureInformationDto, gfiProcessState);
-            log.info("External failure information [MetaId: " + importDataDto.getMetaId() + "] from " + importDataDto.getSource() + " imported (inserted).");
+            log.info("External failure information [MetaId: " + importDataDto.getMetaId() + "] from "
+                    + importDataDto.getSource() + " imported (inserted).");
 
             if (foreignFailureDataDto.isAutopublish()) {
                 failureInformationService.insertPublicationChannelForFailureInfo(retVal.getUuid(), Constants.PUBLICATION_CHANNEL_OWNDMZ, true);
@@ -117,6 +125,13 @@
             return retVal;
         } else {
 
+            if (foreignFailureDataDto.isOnceOnlyImport()) {
+                log.debug("External failure information [MetaId: " + importDataDto.getMetaId() + "] from "
+                        + importDataDto.getSource() + " won't be imported because it has already been imported" +
+                        " once and flag isOnceOnlyImport is true.");
+                return null;
+            }
+
             UUID statusInternIdExistingDto = existingDto.getStatusInternId();
 
             //When status of already existing failureinformation completed or canceled do not update but log it.
@@ -128,8 +143,30 @@
                 return null;
             }
 
+            FailureInformationDto existingDtoClone = null;
+            try {
+                existingDtoClone = objectMapper
+                        .readValue(objectMapper.writeValueAsString(existingDto), FailureInformationDto.class);
+            } catch (JsonProcessingException e) {
+                log.error("Error parsing object (JSON)", e);
+            }
+
             FailureInformationDto updatedDto = setUpdateFromForeignDto(importDataDto, foreignFailureDataDto, existingDto);
 
+            //Is the content of the new failureinformation different compared to the already existing one
+            if (foreignFailureDataDto.isExcludeEquals() && updatedDto.equals(existingDtoClone)){
+                log.debug("External failure information [MetaId: " + importDataDto.getMetaId() + "] from "
+                        + importDataDto.getSource() + " hasn't changed, no update will be executed.");
+                return null;
+            }
+
+            //Don't update if the failureinformation was already edited by an user
+            if (foreignFailureDataDto.isExcludeAlreadyEdited() && !Objects.equals(updatedDto.getModUser(), existingDtoClone.getModUser())){
+                log.debug("External failure information [MetaId: " + importDataDto.getMetaId() + "] from "
+                        + importDataDto.getSource() + " has already been edited in SIT by an user, no update will be executed.");
+                return null;
+            }
+
             if(!foreignFailureDataDto.isAutopublish() && statusInternIdExistingDto.equals(
                     statusService.getStatusFromId(GfiProcessState.QUALIFIED.getStatusValue()).getUuid()
             )) {
@@ -138,8 +175,9 @@
                 );
             } else {
                 if (foreignFailureDataDto.isAutopublish()) {
-                    processHelper.resetPublishedStateForChannels(updatedDto);
-                    log.info("Autopublish for external failure information [" + importDataDto.getMetaId() + "] from " + importDataDto.getSource() + " is true, current status remains unchanged.");
+                    processHelper.resetPublishedStateForChannels(updatedDto); //FIXME richtig?
+                    log.info("Autopublish for external failure information [MetaId: " + importDataDto.getMetaId() + "] from "
+                            + importDataDto.getSource() + " is true, current status remains unchanged.");
                 }
             }
 
@@ -156,11 +194,13 @@
 
         setFromForeignDto(importDataDto, foreignFailureDataDto, failureInformationDto);
         failureInformationDto.setCreateUser(importDataDto.getSource());
+        failureInformationDto.setModUser(importDataDto.getSource());
         return failureInformationDto;
     }
 
     private FailureInformationDto setUpdateFromForeignDto(ImportDataDto importDataDto, ForeignFailureDataDto foreignFailureDataDto, FailureInformationDto failureInformationDto) {
         setFromForeignDto(importDataDto, foreignFailureDataDto, failureInformationDto);
+        failureInformationDto.setModUser(importDataDto.getSource());
         return failureInformationDto;
     }
 
diff --git a/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/viewmodel/FailureInformationDto.java b/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/viewmodel/FailureInformationDto.java
index 11ae178..529ae1d 100644
--- a/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/viewmodel/FailureInformationDto.java
+++ b/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/viewmodel/FailureInformationDto.java
@@ -17,12 +17,15 @@
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import lombok.Data;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Objects;
 import java.util.UUID;
 
 @Data
@@ -102,4 +105,21 @@
 
     private List<ArrayList<BigDecimal>> addressPolygonPoints;
     private List<UUID> stationIds;
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+
+        if (!(o instanceof FailureInformationDto)) return false;
+
+        FailureInformationDto that = (FailureInformationDto) o;
+
+        return new EqualsBuilder().append(isPlanned, that.isPlanned).append(uuid, that.uuid).append(title,
+                that.title).append(description, that.description).append(versionNumber, that.versionNumber).append(responsibility, that.responsibility).append(voltageLevel, that.voltageLevel).append(pressureLevel, that.pressureLevel).append(failureBegin, that.failureBegin).append(failureEndPlanned, that.failureEndPlanned).append(failureEndResupplied, that.failureEndResupplied).append(internalRemark, that.internalRemark).append(postcode, that.postcode).append(city, that.city).append(district, that.district).append(street, that.street).append(housenumber, that.housenumber).append(stationId, that.stationId).append(stationDescription, that.stationDescription).append(stationCoords, that.stationCoords).append(freetextPostcode, that.freetextPostcode).append(freetextCity, that.freetextCity).append(freetextDistrict, that.freetextDistrict).append(longitude, that.longitude).append(latitude, that.latitude).append(objectReferenceExternalSystem, that.objectReferenceExternalSystem).append(publicationStatus, that.publicationStatus).append(publicationFreetext, that.publicationFreetext).append(condensed, that.condensed).append(condensedCount, that.condensedCount).append(faultLocationArea, that.faultLocationArea).append(createUser, that.createUser).append(modUser, that.modUser).append(failureClassificationId, that.failureClassificationId).append(failureClassification, that.failureClassification).append(failureTypeId, that.failureTypeId).append(failureType, that.failureType).append(statusInternId, that.statusInternId).append(statusIntern, that.statusIntern).append(statusExtern, that.statusExtern).append(branchId, that.branchId).append(branch, that.branch).append(branchDescription, that.branchDescription).append(radiusId, that.radiusId).append(radius, that.radius).append(expectedReasonId, that.expectedReasonId).append(expectedReasonText, that.expectedReasonText).append(failureInformationCondensedId, that.failureInformationCondensedId).append(addressPolygonPoints, that.addressPolygonPoints).append(stationIds, that.stationIds).isEquals();
+    }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder(17, 37).append(uuid).append(title).append(description).append(versionNumber).append(responsibility).append(voltageLevel).append(pressureLevel).append(failureBegin).append(failureEndPlanned).append(failureEndResupplied).append(internalRemark).append(postcode).append(city).append(district).append(street).append(housenumber).append(stationId).append(stationDescription).append(stationCoords).append(freetextPostcode).append(freetextCity).append(freetextDistrict).append(longitude).append(latitude).append(objectReferenceExternalSystem).append(publicationStatus).append(publicationFreetext).append(condensed).append(condensedCount).append(faultLocationArea).append(createUser).append(modUser).append(failureClassificationId).append(failureClassification).append(isPlanned).append(failureTypeId).append(failureType).append(statusInternId).append(statusIntern).append(statusExtern).append(branchId).append(branch).append(branchDescription).append(radiusId).append(radius).append(expectedReasonId).append(expectedReasonText).append(failureInformationCondensedId).append(addressPolygonPoints).append(stationIds).toHashCode();
+    }
 }
diff --git a/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/viewmodel/ForeignFailureDataDto.java b/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/viewmodel/ForeignFailureDataDto.java
index a1846d3..1971e55 100644
--- a/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/viewmodel/ForeignFailureDataDto.java
+++ b/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/viewmodel/ForeignFailureDataDto.java
@@ -32,6 +32,12 @@
 
     private boolean isAutopublish;
 
+    private boolean isOnceOnlyImport;
+
+    private boolean isExcludeEquals;
+
+    private boolean isExcludeAlreadyEdited;
+
     @NotNull
     private boolean isPlanned;