forked from CGM_Public/pretix_original
* Allow the manual ordering of questions Update Unit Tests Fix some typos * Add migrations * Minor notation change
81 lines
3.4 KiB
Python
81 lines
3.4 KiB
Python
from django import forms
|
|
from django.utils.functional import cached_property
|
|
|
|
from pretix.base.models import CartPosition, OrderPosition, QuestionAnswer
|
|
from pretix.presale.forms.checkout import QuestionsForm
|
|
|
|
|
|
class QuestionsViewMixin:
|
|
@cached_property
|
|
def forms(self):
|
|
"""
|
|
A list of forms with one form for each cart position that has questions
|
|
the user can answer. All forms have a custom prefix, so that they can all be
|
|
submitted at once.
|
|
"""
|
|
formlist = []
|
|
for cr in self.positions:
|
|
cartpos = cr if isinstance(cr, CartPosition) else None
|
|
orderpos = cr if isinstance(cr, OrderPosition) else None
|
|
form = QuestionsForm(event=self.request.event,
|
|
prefix=cr.id,
|
|
cartpos=cartpos,
|
|
orderpos=orderpos,
|
|
data=(self.request.POST if self.request.method == 'POST' else None))
|
|
form.pos = cartpos or orderpos
|
|
if len(form.fields) > 0:
|
|
formlist.append(form)
|
|
return formlist
|
|
|
|
def save(self):
|
|
failed = False
|
|
for form in self.forms:
|
|
# Every form represents a CartPosition or OrderPosition with questions attached
|
|
if not form.is_valid():
|
|
failed = True
|
|
else:
|
|
# This form was correctly filled, so we store the data as
|
|
# answers to the questions / in the CartPosition object
|
|
for k, v in form.cleaned_data.items():
|
|
if k == 'attendee_name':
|
|
form.pos.attendee_name = v if v != '' else None
|
|
form.pos.save()
|
|
elif k.startswith('question_') and v is not None:
|
|
field = form.fields[k]
|
|
if hasattr(field, 'answer'):
|
|
# We already have a cached answer object, so we don't
|
|
# have to create a new one
|
|
if v == '':
|
|
field.answer.delete()
|
|
else:
|
|
self._save_to_answer(field, field.answer, v)
|
|
field.answer.save()
|
|
elif v != '':
|
|
answer = QuestionAnswer(
|
|
cartposition=(form.pos if isinstance(form.pos, CartPosition) else None),
|
|
orderposition=(form.pos if isinstance(form.pos, OrderPosition) else None),
|
|
question=field.question,
|
|
)
|
|
self._save_to_answer(field, answer, v)
|
|
answer.save()
|
|
return not failed
|
|
|
|
def _save_to_answer(self, field, answer, value):
|
|
if isinstance(field, forms.ModelMultipleChoiceField):
|
|
answstr = ", ".join([str(o) for o in value])
|
|
if not answer.pk:
|
|
answer.save()
|
|
else:
|
|
answer.options.clear()
|
|
answer.answer = answstr
|
|
answer.options.add(*value)
|
|
elif isinstance(field, forms.ModelChoiceField):
|
|
if not answer.pk:
|
|
answer.save()
|
|
else:
|
|
answer.options.clear()
|
|
answer.options.add(value)
|
|
answer.answer = value.answer
|
|
else:
|
|
answer.answer = value
|