From 5e76cf2040d1e261a7bc4c80e0b3ee1b14acbd41 Mon Sep 17 00:00:00 2001
From: Jan Tymel <410388@mail.muni.cz>
Date: Thu, 21 Jan 2021 22:49:41 +0100
Subject: [PATCH] Align DecisionMatrixRows when phases' order are changed

Resolves #1
---
 .../demo/repository/PhaseLevelRepository.java |  4 ++
 .../demo/service/LevelOperationsService.java  |  5 +-
 .../demo/service/PhaseLevelService.java       | 61 +++++++++++++++++++
 3 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/src/main/java/com/example/demo/repository/PhaseLevelRepository.java b/src/main/java/com/example/demo/repository/PhaseLevelRepository.java
index 99ac0f35..f71587d1 100644
--- a/src/main/java/com/example/demo/repository/PhaseLevelRepository.java
+++ b/src/main/java/com/example/demo/repository/PhaseLevelRepository.java
@@ -5,8 +5,12 @@ import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.query.Param;
 
+import java.util.List;
+
 public interface PhaseLevelRepository extends JpaRepository<PhaseLevel, Long> {
 
     @Query("SELECT COUNT(p.id) FROM PhaseLevel p WHERE p.trainingDefinitionId = :trainingDefinitionId")
     int getNumberOfExistingPhases(@Param("trainingDefinitionId") Long trainingDefinitionId);
+
+    List<PhaseLevel> findAllByTrainingDefinitionIdOrderByOrder(Long trainingDefinitionId);
 }
diff --git a/src/main/java/com/example/demo/service/LevelOperationsService.java b/src/main/java/com/example/demo/service/LevelOperationsService.java
index 135b035b..77e81f7b 100644
--- a/src/main/java/com/example/demo/service/LevelOperationsService.java
+++ b/src/main/java/com/example/demo/service/LevelOperationsService.java
@@ -74,11 +74,10 @@ public class LevelOperationsService {
             return;
         }
 
-        // TODO change decision matrix
-
         levelFrom.get().setOrder(newPosition);
-
         baseLevelRepository.save(levelFrom.get());
+
+        phaseLevelService.alignDecisionMatrixForPhasesInTrainingDefinition(levelFrom.get().getTrainingDefinitionId());
     }
 
     @Transactional
diff --git a/src/main/java/com/example/demo/service/PhaseLevelService.java b/src/main/java/com/example/demo/service/PhaseLevelService.java
index 5b869dc1..c8f8c020 100644
--- a/src/main/java/com/example/demo/service/PhaseLevelService.java
+++ b/src/main/java/com/example/demo/service/PhaseLevelService.java
@@ -13,8 +13,11 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 @Service
 public class PhaseLevelService {
@@ -63,6 +66,14 @@ public class PhaseLevelService {
         return BeanMapper.INSTANCE.toDto(savedEntity);
     }
 
+    public void alignDecisionMatrixForPhasesInTrainingDefinition(Long trainingDefinitionId) {
+        List<PhaseLevel> phaseLevels = phaseLevelRepository.findAllByTrainingDefinitionIdOrderByOrder(trainingDefinitionId);
+
+        for (PhaseLevel phaseLevel : phaseLevels) {
+            alignDecisionMatrixForPhase(phaseLevel);
+        }
+    }
+
     private List<DecisionMatrixRow> prepareDefaultDecisionMatrix(Long trainingDefinitionId, PhaseLevel phaseLevel) {
         List<DecisionMatrixRow> result = new ArrayList<>();
 
@@ -79,4 +90,54 @@ public class PhaseLevelService {
 
         return result;
     }
+
+    private void alignDecisionMatrixForPhase(PhaseLevel phaseLevel) {
+        if (Objects.isNull(phaseLevel)) {
+            return;
+        }
+
+        int numberOfRows = 0;
+        if (!CollectionUtils.isEmpty(phaseLevel.getDecisionMatrix())) {
+            numberOfRows = phaseLevel.getDecisionMatrix().size();
+        }
+
+        final int expextedNumberOfRows = phaseLevel.getOrder() + 1;
+
+        if (numberOfRows == expextedNumberOfRows) {
+            return;
+        } else if (numberOfRows < expextedNumberOfRows) {
+            List<DecisionMatrixRow> newDecisionMatrixRows = getNewDecisionMatrixRows(numberOfRows, expextedNumberOfRows, phaseLevel);
+            phaseLevel.getDecisionMatrix().addAll(newDecisionMatrixRows);
+        } else {
+            List<DecisionMatrixRow> neededDecisionMatrixRows = getOnlyNeededDecisionMatrixRows(expextedNumberOfRows, phaseLevel);
+
+            phaseLevel.getDecisionMatrix().clear();
+            phaseLevel.getDecisionMatrix().addAll(neededDecisionMatrixRows);
+        }
+
+        phaseLevelRepository.save(phaseLevel);
+    }
+
+    private List<DecisionMatrixRow> getNewDecisionMatrixRows(int currentNumberOfNewRows, int expectedNumberOfRows,  PhaseLevel phaseLevel) {
+        List<DecisionMatrixRow> result = new ArrayList<>();
+        for (int i = currentNumberOfNewRows; i < expectedNumberOfRows; i++) {
+            DecisionMatrixRow decisionMatrixRow = new DecisionMatrixRow();
+            decisionMatrixRow.setPhaseLevel(phaseLevel);
+            decisionMatrixRow.setOrder(i);
+
+            result.add(decisionMatrixRow);
+        }
+
+        return result;
+    }
+
+    private List<DecisionMatrixRow> getOnlyNeededDecisionMatrixRows(int expectedNumberOfRows, PhaseLevel phaseLevel) {
+        List<DecisionMatrixRow> decisionMatrix = phaseLevel.getDecisionMatrix();
+
+        return decisionMatrix.stream()
+                .sorted(Comparator.comparingInt(DecisionMatrixRow::getOrder))
+                .limit(expectedNumberOfRows)
+                .collect(Collectors.toList());
+
+    }
 }
-- 
GitLab