mirror of
https://github.com/pretix/pretix.git
synced 2026-05-07 15:34:02 +00:00
Allow dependencies between questions (#1202)
- [x] data model - [x] api - [x] backend editor - [x] backend validation logic - [x] frontend display logic - [x] frontend validation logic - [x] test checkout step - [x] test modify order in frontend - [x] test modify order in backend - [x] validation tests - [x] correctly evaluate dependency tree in frontend? - [x] copy events
This commit is contained in:
@@ -414,10 +414,34 @@ class QuestionsStep(QuestionsViewMixin, CartMixin, TemplateFlowStep):
|
||||
|
||||
for cp in self._positions_for_questions:
|
||||
answ = {
|
||||
aw.question_id: aw.answer for aw in cp.answerlist
|
||||
aw.question_id: aw for aw in cp.answerlist
|
||||
}
|
||||
question_cache = {
|
||||
q.pk: q for q in cp.item.questions_to_ask
|
||||
}
|
||||
|
||||
def question_is_visible(parentid, qval):
|
||||
parentq = question_cache[parentid]
|
||||
if parentq.dependency_question_id and not question_is_visible(parentq.dependency_question_id, parentq.dependency_value):
|
||||
return False
|
||||
if parentid not in answ:
|
||||
return False
|
||||
if qval == 'True':
|
||||
return answ[parentid].answer == 'True'
|
||||
elif qval == 'False':
|
||||
return answ[parentid].answer == 'False'
|
||||
else:
|
||||
return qval in [o.identifier for o in answ[parentid].options.all()]
|
||||
|
||||
def question_is_required(q):
|
||||
return (
|
||||
q.required and
|
||||
(not q.dependency_question_id or question_is_visible(q.dependency_question_id, q.dependency_value))
|
||||
)
|
||||
|
||||
for q in cp.item.questions_to_ask:
|
||||
if q.required and q.id not in answ:
|
||||
print("question", q, "is required", question_is_required(q), "has answer", q.id in answ)
|
||||
if question_is_required(q) and not answ.get(q.id):
|
||||
if warn:
|
||||
messages.warning(request, _('Please fill in answers to all required questions.'))
|
||||
return False
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<script type="text/javascript" src="{% static "bootstrap/js/bootstrap.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "datetimepicker/bootstrap-datetimepicker.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "pretixcontrol/js/jquery.qrcode.min.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "pretixpresale/js/ui/questions.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "pretixpresale/js/ui/main.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "pretixbase/js/asynctask.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "pretixbase/js/details.js" %}"></script>
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
</h4>
|
||||
</summary>
|
||||
<div>
|
||||
<div class="panel-body" data-idx="{{ forloop.counter0 }}">
|
||||
<div class="panel-body questions-form" data-idx="{{ forloop.counter0 }}">
|
||||
{% if pos.addons.all %}
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">
|
||||
@@ -97,7 +97,7 @@
|
||||
{# Add-Ons #}
|
||||
<legend>+ {{ form.pos.item }}</legend>
|
||||
{% endif %}
|
||||
{% bootstrap_form form layout="horizontal" %}
|
||||
{% bootstrap_form form layout="checkout" %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -53,13 +53,13 @@
|
||||
</h4>
|
||||
</summary>
|
||||
<div id="cp{{ pos.id }}">
|
||||
<div class="panel-body">
|
||||
<div class="panel-body questions-form">
|
||||
{% for form in forms %}
|
||||
{% if form.pos.item != pos.item %}
|
||||
{# Add-Ons #}
|
||||
<legend>+ {{ form.pos.item }}</legend>
|
||||
{% endif %}
|
||||
{% bootstrap_form form layout="horizontal" %}
|
||||
{% bootstrap_form form layout="checkout" %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,7 @@ class QuestionsViewMixin(BaseQuestionsViewMixin):
|
||||
|
||||
@cached_property
|
||||
def _positions_for_questions(self):
|
||||
qqs = Question.objects.all()
|
||||
qqs = self.request.event.questions.all()
|
||||
if self.only_user_visible:
|
||||
qqs = qqs.filter(ask_during_checkin=False)
|
||||
cart = get_cart(self.request).select_related(
|
||||
@@ -33,7 +33,7 @@ class QuestionsViewMixin(BaseQuestionsViewMixin):
|
||||
Question.objects.none(),
|
||||
to_attr='dummy'
|
||||
)))
|
||||
),
|
||||
).select_related('dependency_question'),
|
||||
to_attr='questions_to_ask')
|
||||
)
|
||||
return sorted(list(cart), key=self._keyfunc)
|
||||
|
||||
Reference in New Issue
Block a user