SI-592_Grid State Updated
diff --git a/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/GfiGrid.java b/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/GfiGrid.java
index 3d8d943..b4bc353 100644
--- a/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/GfiGrid.java
+++ b/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/GfiGrid.java
@@ -20,10 +20,7 @@
 import org.eclipse.openk.gridfailureinformation.bpmn.base.ProcessGrid;
 import org.eclipse.openk.gridfailureinformation.bpmn.base.ProcessTask;
 import org.eclipse.openk.gridfailureinformation.bpmn.base.tasks.DecisionTask;
-import org.eclipse.openk.gridfailureinformation.bpmn.impl.tasks.DecideFailureInfoCanceled;
-import org.eclipse.openk.gridfailureinformation.bpmn.impl.tasks.DecideFailureInfoPlanned;
-import org.eclipse.openk.gridfailureinformation.bpmn.impl.tasks.ShortcutTask;
-import org.eclipse.openk.gridfailureinformation.bpmn.impl.tasks.UIStoreFailureInformationTask;
+import org.eclipse.openk.gridfailureinformation.bpmn.impl.tasks.*;
 import org.springframework.stereotype.Component;
 
 import static org.eclipse.openk.gridfailureinformation.bpmn.base.tasks.DecisionTask.OutputPort.NO;
@@ -56,6 +53,12 @@
         ProcessTask publishMessage = register( QUALIFIED,
                 new UIStoreFailureInformationTask( "State QUALIFIED UI Task", true));
 
+        DecisionTask decideUpdated = new DecideFailureInfoUpdated();
+        ProcessTask storeEditStatusUpdated = new ShortcutTask( UPDATED );
+
+        ProcessTask completedEndpoint = register( COMPLETED,
+                new UIStoreFailureInformationTask( "State COMPETED UI Task", true));
+
         //Connect
 
         //Geplante Meldung?
@@ -71,6 +74,13 @@
         //Meldung storniert?
         decideCanceled.connectOutputTo( YES, storeEditStatusCanceled ); //Status nicht speichern da sonst doppelt, -> nächster Porzessschritt
         decideCanceled.connectOutputTo( NO, storeEditStatusQualified ); //Status nicht speichern da sonst doppelt, -> nächster Porzessschritt
+
+        storeEditStatusQualified.connectOutputTo(publishMessage);
+        publishMessage.connectOutputTo(decideUpdated);
+        decideUpdated.connectOutputTo(YES, storeEditStatusUpdated);
+        decideUpdated.connectOutputTo(NO, completedEndpoint);
+
+        storeEditStatusUpdated.connectOutputTo(qualifyMessage);
     }
 
 }
diff --git a/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/tasks/DecideFailureInfoUpdated.java b/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/tasks/DecideFailureInfoUpdated.java
new file mode 100644
index 0000000..11538aa
--- /dev/null
+++ b/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/tasks/DecideFailureInfoUpdated.java
@@ -0,0 +1,52 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2018 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************
+ */
+
+package org.eclipse.openk.gridfailureinformation.bpmn.impl.tasks;
+
+import lombok.extern.log4j.Log4j2;
+import org.eclipse.openk.gridfailureinformation.bpmn.base.ProcessException;
+import org.eclipse.openk.gridfailureinformation.bpmn.base.ProcessState;
+import org.eclipse.openk.gridfailureinformation.bpmn.base.tasks.DecisionTask;
+import org.eclipse.openk.gridfailureinformation.bpmn.impl.GfiProcessState;
+import org.eclipse.openk.gridfailureinformation.bpmn.impl.GfiProcessSubject;
+import org.eclipse.openk.gridfailureinformation.exceptions.InternalServerErrorException;
+
+@Log4j2
+public class DecideFailureInfoUpdated extends DecisionTask<GfiProcessSubject> {
+
+    public DecideFailureInfoUpdated() {
+        super("Decision: Ist die Störungsinformation aktualisiert?");
+    }
+
+    @Override
+    public OutputPort decide(GfiProcessSubject subject) throws ProcessException {
+        ProcessState newState = subject.getProcessHelper().getProcessStateFromStatusUuid(
+                subject.getFailureInformationDto().getStatusInternId());
+
+        String loggerOutput1 = "Decide: ";
+
+        if (newState == GfiProcessState.UPDATED) {
+            log.debug(loggerOutput1 + getDescription() + "\" -> Firing YES");
+            return OutputPort.YES;
+        } else if (newState == GfiProcessState.COMPLETED) {
+            log.debug(loggerOutput1 + getDescription() + "\" -> Firing NO");
+            return OutputPort.NO;
+        } else {
+            throw new ProcessException(this.getDescription() + ": Invalid status request:" + newState,
+                    new InternalServerErrorException("invalid.status.request"));
+        }
+    }
+
+}
diff --git a/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/tasks/UIStoreFailureInformationTask.java b/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/tasks/UIStoreFailureInformationTask.java
index bc2e329..310c0d2 100644
--- a/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/tasks/UIStoreFailureInformationTask.java
+++ b/gfsBackendService/src/main/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/tasks/UIStoreFailureInformationTask.java
@@ -35,7 +35,9 @@
 
     @Override
     protected void onLeaveStep(GfiProcessSubject subject) throws ProcessException {
-        subject.getProcessHelper().storeFailureFromViewModel(subject.getFailureInformationDto());
+        subject.setFailureInformationDto(  // store and refresh the dto in the subject
+            subject.getProcessHelper().storeFailureFromViewModel(subject.getFailureInformationDto())
+        );
     }
 
     @Override
@@ -51,7 +53,7 @@
     @Override
     protected void onStayInTask(GfiProcessSubject subject) throws ProcessException {
         FailureInformationDto failureInformationDto = subject.getProcessHelper().storeFailureFromViewModel(subject.getFailureInformationDto());
-        subject.setFailureInformationDto(failureInformationDto);
+        subject.setFailureInformationDto(failureInformationDto); // store and refresh the dto in the subject
     }
 
     private boolean detectStateChanged( GfiProcessSubject subject ) {
diff --git a/gfsBackendService/src/test/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/DecideFailureInfoCanceledTest.java b/gfsBackendService/src/test/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/DecideFailureInfoCanceledTest.java
index 55c073c..31468a7 100644
--- a/gfsBackendService/src/test/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/DecideFailureInfoCanceledTest.java
+++ b/gfsBackendService/src/test/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/DecideFailureInfoCanceledTest.java
@@ -14,6 +14,7 @@
 import org.eclipse.openk.gridfailureinformation.support.MockDataHelper;
 import org.eclipse.openk.gridfailureinformation.viewmodel.FailureInformationDto;
 import org.junit.jupiter.api.Test;
+import org.mockito.stubbing.Answer;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
@@ -63,10 +64,13 @@
         when(processHelper.getProcessStateFromStatusUuid(any( UUID.class ))).thenReturn(GfiProcessState.CANCELED);
         when(statusRepository.findByUuid(any( UUID.class ))).thenReturn(Optional.of(refStatus));
         when(failureInformationRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(fiTbl));
-        when(failureInformationRepository.save(any(TblFailureInformation.class))).thenReturn(fiTbl);
         when(stationRepository.findByStationId(anyString())).thenReturn(Optional.of(tblStation));
         when(addressRepository.findByStationId(anyString())).thenReturn(addressList);
-
+        when( processHelper.storeFailureFromViewModel(any(FailureInformationDto.class)))
+                .then((Answer<FailureInformationDto>) invocation -> {
+                    Object[] args = invocation.getArguments();
+                    return (FailureInformationDto) args[0];
+                });
         FailureInformationDto savedDto = failureInformationService.updateFailureInfo(fiDto);
         //TODO verify CANCELED
         assertEquals(fiDto.getUuid(), savedDto.getUuid());
@@ -87,10 +91,13 @@
         when(processHelper.getProcessStateFromStatusUuid(any( UUID.class ))).thenReturn(GfiProcessState.QUALIFIED);
         when(statusRepository.findByUuid(any( UUID.class ))).thenReturn(Optional.of(refStatus));
         when(failureInformationRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(fiTbl));
-        when(failureInformationRepository.save(any(TblFailureInformation.class))).thenReturn(fiTbl);
         when(stationRepository.findByStationId(anyString())).thenReturn(Optional.of(tblStation));
         when(addressRepository.findByStationId(anyString())).thenReturn(addressList);
-
+        when( processHelper.storeFailureFromViewModel(any(FailureInformationDto.class)))
+                .then((Answer<FailureInformationDto>) invocation -> {
+                    Object[] args = invocation.getArguments();
+                    return (FailureInformationDto) args[0];
+                });
         FailureInformationDto savedDto = failureInformationService.updateFailureInfo(fiDto);
         //TODO verify Qualified
         assertEquals(fiDto.getUuid(), savedDto.getUuid());
diff --git a/gfsBackendService/src/test/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/DecideFailureInfoUpdatedTest.java b/gfsBackendService/src/test/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/DecideFailureInfoUpdatedTest.java
new file mode 100644
index 0000000..55538ca
--- /dev/null
+++ b/gfsBackendService/src/test/java/org/eclipse/openk/gridfailureinformation/bpmn/impl/DecideFailureInfoUpdatedTest.java
@@ -0,0 +1,116 @@
+package org.eclipse.openk.gridfailureinformation.bpmn.impl;
+
+import org.eclipse.openk.gridfailureinformation.bpmn.impl.tasks.ProcessHelper;
+import org.eclipse.openk.gridfailureinformation.config.TestConfiguration;
+import org.eclipse.openk.gridfailureinformation.model.RefStatus;
+import org.eclipse.openk.gridfailureinformation.model.TblAddress;
+import org.eclipse.openk.gridfailureinformation.model.TblFailureInformation;
+import org.eclipse.openk.gridfailureinformation.model.TblStation;
+import org.eclipse.openk.gridfailureinformation.repository.AddressRepository;
+import org.eclipse.openk.gridfailureinformation.repository.FailureInformationRepository;
+import org.eclipse.openk.gridfailureinformation.repository.StationRepository;
+import org.eclipse.openk.gridfailureinformation.repository.StatusRepository;
+import org.eclipse.openk.gridfailureinformation.service.FailureInformationService;
+import org.eclipse.openk.gridfailureinformation.support.MockDataHelper;
+import org.eclipse.openk.gridfailureinformation.viewmodel.FailureInformationDto;
+import org.junit.jupiter.api.Test;
+import org.mockito.stubbing.Answer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.test.context.ContextConfiguration;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
+
+@DataJpaTest
+@ContextConfiguration(classes = {TestConfiguration.class})
+public class DecideFailureInfoUpdatedTest {
+
+    @Qualifier("myFailureInformationService")
+    @Autowired
+    private FailureInformationService failureInformationService;
+
+    @MockBean
+    private ProcessHelper processHelper;
+    @MockBean
+    private StatusRepository statusRepository;
+    @MockBean
+    private FailureInformationRepository failureInformationRepository;
+    @MockBean
+    private StationRepository stationRepository;
+    @MockBean
+    private AddressRepository addressRepository;
+
+    @Test
+    public void shouldCall_DecideFailureInfoUpdated_Result_Updated() {
+        RefStatus refStatus = MockDataHelper.mockRefStatus();
+        refStatus.setId(GfiProcessState.QUALIFIED.getStatusValue());
+        refStatus.setStatus("qualified");
+
+        FailureInformationDto fiDto = MockDataHelper.mockFailureInformationDto();
+        UUID statusUpdated = UUID.randomUUID();
+        fiDto.setStatusInternId(statusUpdated);
+
+        TblFailureInformation fiTbl = MockDataHelper.mockTblFailureInformation();
+        fiTbl.setId(777L);
+        TblStation tblStation = MockDataHelper.mockTblStation();
+        List<TblAddress> addressList = MockDataHelper.mockTblAddressList();
+
+        when(processHelper.getProcessStateFromStatusUuid(any( UUID.class ))).thenReturn(GfiProcessState.UPDATED);
+        when(statusRepository.findByUuid(any( UUID.class ))).thenReturn(Optional.of(refStatus));
+        when(failureInformationRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(fiTbl));
+        when(stationRepository.findByStationId(anyString())).thenReturn(Optional.of(tblStation));
+        when(addressRepository.findByStationId(anyString())).thenReturn(addressList);
+        when( processHelper.storeFailureFromViewModel(any(FailureInformationDto.class)))
+                .then((Answer<FailureInformationDto>) invocation -> {
+                    Object[] args = invocation.getArguments();
+                    return (FailureInformationDto) args[0];
+                });
+
+        FailureInformationDto savedDto = failureInformationService.updateFailureInfo(fiDto);
+
+        assertEquals(fiDto.getUuid(), savedDto.getUuid());
+        assertEquals(statusUpdated, fiDto.getStatusInternId());
+    }
+
+    @Test
+    public void shouldCall_DecideFailureInfoUpdated_Result_Completed() {
+        RefStatus refStatus = MockDataHelper.mockRefStatus();
+        refStatus.setId(GfiProcessState.QUALIFIED.getStatusValue());
+        refStatus.setStatus("qualified");
+
+        FailureInformationDto fiDto = MockDataHelper.mockFailureInformationDto();
+        UUID statusCompleted = UUID.randomUUID();
+        fiDto.setStatusInternId(statusCompleted);
+
+        TblFailureInformation fiTbl = MockDataHelper.mockTblFailureInformation();
+        fiTbl.setId(777L);
+        TblStation tblStation = MockDataHelper.mockTblStation();
+        List<TblAddress> addressList = MockDataHelper.mockTblAddressList();
+
+        when(processHelper.getProcessStateFromStatusUuid(any( UUID.class ))).thenReturn(GfiProcessState.COMPLETED);
+        when(statusRepository.findByUuid(any( UUID.class ))).thenReturn(Optional.of(refStatus));
+        when(failureInformationRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(fiTbl));
+        when(stationRepository.findByStationId(anyString())).thenReturn(Optional.of(tblStation));
+        when(addressRepository.findByStationId(anyString())).thenReturn(addressList);
+        when( processHelper.storeFailureFromViewModel(any(FailureInformationDto.class)))
+                .then((Answer<FailureInformationDto>) invocation -> {
+                    Object[] args = invocation.getArguments();
+                    return (FailureInformationDto) args[0];
+                });
+
+        FailureInformationDto savedDto = failureInformationService.updateFailureInfo(fiDto);
+
+        assertEquals(fiDto.getUuid(), savedDto.getUuid());
+        assertEquals(statusCompleted, fiDto.getStatusInternId());
+    }
+
+}