-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1965 from open-dynaMIX/fix_recalculate_calc_answers
fix: replace faulty migration for calc answers with a command
- Loading branch information
Showing
4 changed files
with
109 additions
and
135 deletions.
There are no files selected for viewing
35 changes: 35 additions & 0 deletions
35
caluma/caluma_form/management/commands/recalculate_calc_answers.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
from django.core.management.base import BaseCommand | ||
|
||
from caluma.caluma_form.models import Answer, Question | ||
from caluma.caluma_form.signals import _update_or_create_calc_answer | ||
|
||
|
||
class Command(BaseCommand): | ||
""" | ||
Recalculate calculated answers containing values from TableAnswers. | ||
Due to a bug, answers to calculated questions were wrong, if they contained values | ||
from table rows. This command recalculates all of them. | ||
""" | ||
|
||
help = "Recalculate calculated answers containing values from TableAnswers." | ||
|
||
def handle(self, *args, **options): | ||
affected_questions = ( | ||
Question.objects.filter(type="table") | ||
.exclude(calc_dependents=[]) | ||
.values_list("calc_dependents", flat=True) | ||
) | ||
|
||
affected_questions_clean = set( | ||
[slug for entry in affected_questions for slug in entry] | ||
) | ||
|
||
calc_answers = Answer.objects.filter( | ||
question__type="calculated_float", | ||
document__isnull=False, | ||
question__slug__in=affected_questions_clean, | ||
) | ||
|
||
for answer in calc_answers.iterator(): | ||
_update_or_create_calc_answer(answer.question, answer.document) |
54 changes: 0 additions & 54 deletions
54
caluma/caluma_form/migrations/0047_recalculate_calc_answers.py
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
caluma/caluma_form/tests/test_recalculate_calc_answers_command.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import os | ||
|
||
from django.core.management import call_command | ||
|
||
from caluma.caluma_form.api import save_answer, save_document | ||
from caluma.caluma_form.models import Question | ||
|
||
|
||
def test_recalculate_calc_answers( | ||
db, | ||
form_factory, | ||
question_factory, | ||
form_question_factory, | ||
): | ||
# set up form structure | ||
main_form_question = form_question_factory( | ||
question__type=Question.TYPE_INTEGER, question__slug="dep1_main" | ||
) | ||
main_form = main_form_question.form | ||
dep1_main = main_form_question.question | ||
|
||
row_form = form_factory(slug="row_form") | ||
table_question = question_factory( | ||
type="table", | ||
slug="table_question", | ||
row_form=row_form, | ||
is_required="true", | ||
is_hidden="false", | ||
) | ||
form_question_factory(form=main_form, question=table_question) | ||
|
||
row_form_question = form_question_factory( | ||
form=row_form, | ||
question__type=Question.TYPE_INTEGER, | ||
question__slug="dep2_row", | ||
question__is_required=True, | ||
) | ||
dep2_row = row_form_question.question | ||
|
||
form_question_factory( | ||
form=main_form, | ||
question__slug="calc_question", | ||
question__type=Question.TYPE_CALCULATED_FLOAT, | ||
question__calc_expression=( | ||
f'"dep1_main"|answer(0) + "{table_question.slug}"|answer([])|mapby("dep2_row")|sum' | ||
), | ||
) | ||
|
||
# assert calc_dependents | ||
dep1_main.refresh_from_db() | ||
dep2_row.refresh_from_db() | ||
assert dep1_main.calc_dependents == ["calc_question"] | ||
assert dep2_row.calc_dependents == ["calc_question"] | ||
|
||
# set up document and answers | ||
main_doc = save_document(form=main_form) | ||
save_answer(question=dep1_main, value=10, document=main_doc) | ||
row_doc = save_document(form=row_form) | ||
save_answer(question=dep2_row, value=13, document=row_doc) | ||
save_answer(table_question, document=main_doc, value=[str(row_doc.pk)]) | ||
calc_answer = main_doc.answers.get(question_id="calc_question") | ||
|
||
# assert calc bug is fixed | ||
assert calc_answer.value == 23 | ||
|
||
# set calc_answer.value to 10, like it would have been without the fix | ||
calc_answer.value = 10 | ||
calc_answer.save() | ||
|
||
call_command("recalculate_calc_answers", stderr=open(os.devnull, "w")) | ||
|
||
# assert correct calc_value after migration | ||
calc_answer.refresh_from_db() | ||
assert calc_answer.value == 23 |