From 8d4f4ab1a00c30ccde8595d2cd6dc9fe02961119 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Victor=20L=C3=B6fgren?= <viclo211@student.liu.se>
Date: Tue, 8 Jun 2021 17:02:36 +0200
Subject: [PATCH] Fix problem when deleting alternatives

---
 server/app/apis/alternatives.py          |  8 ++---
 server/app/database/controller/delete.py | 41 ++++++++++++++++++------
 2 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/server/app/apis/alternatives.py b/server/app/apis/alternatives.py
index d4db80fc..8d2636fa 100644
--- a/server/app/apis/alternatives.py
+++ b/server/app/apis/alternatives.py
@@ -46,7 +46,7 @@ class Alternatives(MethodView):
     @blp.authorization(allowed_roles=ALL, allowed_views=ALL)
     @blp.response(http_codes.OK, QuestionAlternativeSchema(many=True))
     def get(self, competition_id, slide_id, question_id):
-        """ Gets the all question alternatives to the specified question. """
+        """Gets the all question alternatives to the specified question."""
         return dbc.get.question_alternative_list(competition_id, slide_id, question_id)
 
     @blp.authorization(allowed_roles=ALL)
@@ -67,7 +67,7 @@ class QuestionAlternatives(MethodView):
     @blp.response(http_codes.OK, QuestionAlternativeSchema)
     @blp.alt_response(http_codes.NOT_FOUND, ErrorSchema, description="Could not find alternative")
     def get(self, competition_id, slide_id, question_id, alternative_id):
-        """ Gets the specified question alternative. """
+        """Gets the specified question alternative."""
         return dbc.get.question_alternative(competition_id, slide_id, question_id, alternative_id)
 
     @blp.authorization(allowed_roles=ALL)
@@ -118,6 +118,6 @@ class QuestionAlternatives(MethodView):
     @blp.alt_response(http_codes.NOT_FOUND, ErrorSchema, description="Could not find alternative")
     @blp.alt_response(http_codes.CONFLICT, ErrorSchema, description="Could not delete alternative")
     def delete(self, competition_id, slide_id, question_id, alternative_id):
-        """ Deletes the specified question alternative. """
-        dbc.delete.default(dbc.get.question_alternative(competition_id, slide_id, question_id, alternative_id))
+        """Deletes the specified question alternative."""
+        dbc.delete.alternative(dbc.get.question_alternative(competition_id, slide_id, question_id, alternative_id))
         return None
diff --git a/server/app/database/controller/delete.py b/server/app/database/controller/delete.py
index d85228cf..7898d0c5 100644
--- a/server/app/database/controller/delete.py
+++ b/server/app/database/controller/delete.py
@@ -5,13 +5,13 @@ This file contains functionality to delete data to the database.
 import app.database.controller as dbc
 from app.apis import http_codes
 from app.core import db
-from app.database.models import QuestionAlternativeAnswer, QuestionScore, Whitelist
+from app.database.models import QuestionAlternative, QuestionAlternativeAnswer, QuestionScore, Whitelist
 from flask_smorest import abort
 from sqlalchemy.exc import IntegrityError
 
 
 def default(item):
-    """ Deletes item and commits. """
+    """Deletes item and commits."""
 
     try:
         db.session.delete(item)
@@ -40,13 +40,13 @@ def whitelist_to_blacklist(filters):
 
 
 def component(item_component):
-    """ Deletes component. """
+    """Deletes component."""
 
     default(item_component)
 
 
 def _slide(item_slide):
-    """ Internal delete for slide. """
+    """Internal delete for slide."""
 
     for item_question in item_slide.questions:
         question(item_question)
@@ -57,7 +57,7 @@ def _slide(item_slide):
 
 
 def slide(item_slide):
-    """ Deletes slide and updates order of other slides if neccesary. """
+    """Deletes slide and updates order of other slides if neccesary."""
 
     competition_id = item_slide.competition_id
     slide_order = item_slide.order
@@ -74,7 +74,7 @@ def slide(item_slide):
 
 
 def team(item_team):
-    """ Deletes team, its question answers and the code. """
+    """Deletes team, its question answers and the code."""
 
     for item_question_answer in item_team.question_alternative_answers:
         default(item_question_answer)
@@ -85,7 +85,7 @@ def team(item_team):
 
 
 def question(item_question):
-    """ Deletes question and its alternatives and answers. """
+    """Deletes question and its alternatives and answers."""
 
     scores = QuestionScore.query.filter(QuestionScore.question_id == item_question.id).all()
 
@@ -99,7 +99,7 @@ def question(item_question):
 
 
 def alternatives(item_alternatives):
-    """ Deletes question alternative. """
+    """Deletes question alternative."""
     answers = QuestionAlternativeAnswer.query.filter(
         QuestionAlternativeAnswer.question_alternative_id == item_alternatives.id
     ).all()
@@ -109,8 +109,29 @@ def alternatives(item_alternatives):
     default(item_alternatives)
 
 
+def alternative(item_alternative):
+    """Deletes specified alternative and updates the order for the remaining alternatives"""
+
+    alternatives_to_same_question = QuestionAlternative.query.filter(
+        QuestionAlternative.question_id == item_alternative.question_id
+    ).all()
+
+    alternative_order = item_alternative.alternative_order
+    correct_order = item_alternative.correct_order
+
+    default(item_alternative)
+
+    for other_alternative in alternatives_to_same_question:
+        if other_alternative.alternative_order > alternative_order:
+            other_alternative.alternative_order -= 1
+        if other_alternative.correct_order > correct_order:
+            other_alternative.correct_order -= 1
+
+    db.session.commit()
+
+
 def competition(item_competition):
-    """ Deletes competition, its slides, teams and codes. """
+    """Deletes competition, its slides, teams and codes."""
 
     for item_slide in item_competition.slides:
         _slide(item_slide)
@@ -123,6 +144,6 @@ def competition(item_competition):
 
 
 def code(item_code):
-    """ Deletes competition code. """
+    """Deletes competition code."""
 
     default(item_code)
-- 
GitLab