mirror of
https://github.com/pretix/pretix.git
synced 2025-12-05 21:32:28 +00:00
Compare commits
1 Commits
fix-order-
...
copy-from-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa372b3df0 |
@@ -1,3 +1,4 @@
|
||||
import itertools
|
||||
import json
|
||||
from collections import OrderedDict
|
||||
from decimal import Decimal
|
||||
@@ -53,7 +54,31 @@ class BaseQuestionsViewMixin:
|
||||
data=(self.request.POST if self.request.method == 'POST' else None),
|
||||
files=(self.request.FILES if self.request.method == 'POST' else None))
|
||||
form.pos = cartpos or orderpos
|
||||
form.show_copy_answers_to_addon_button = form.pos.addon_to and set(form.pos.addon_to.item.questions.all()) & set(form.pos.item.questions.all())
|
||||
|
||||
if form.pos.addon_to_id is not None:
|
||||
form.copy_answer_from = None
|
||||
# addons typically do not have the same item as the main position, so we look for overlapping questions
|
||||
form.show_copy_answers_to_addon_button = bool(
|
||||
set(form.pos.addon_to.item.questions.values_list("id", flat=True)) &
|
||||
set(form.pos.item.questions.values_list("id", flat=True)))
|
||||
else:
|
||||
form.show_copy_answers_to_addon_button = False
|
||||
# look for a position we can best copy answers from
|
||||
form.copy_answer_from = next(
|
||||
itertools.chain(
|
||||
( # match a position with the same item
|
||||
other_form.pos.id for other_form in formlist
|
||||
if other_form.pos.addon_to_id is None and form.pos.item.id == other_form.pos.item.id
|
||||
),
|
||||
( # match a position with questions in common
|
||||
other_form.pos.id for other_form in formlist
|
||||
if other_form.pos.addon_to_id is None
|
||||
and set(form.pos.item.questions.values_list("id", flat=True)) & set(other_form.pos.item.questions.values_list("id", flat=True))
|
||||
)
|
||||
),
|
||||
None # didn't find a position to copy answers from
|
||||
)
|
||||
|
||||
if len(form.fields) > 0:
|
||||
formlist.append(form)
|
||||
return formlist
|
||||
@@ -105,8 +130,7 @@ class BaseQuestionsViewMixin:
|
||||
if hasattr(field, 'answer'):
|
||||
# We already have a cached answer object, so we don't
|
||||
# have to create a new one
|
||||
if v == '' or v is None or (isinstance(field, forms.FileField) and v is False) \
|
||||
or (isinstance(v, QuerySet) and not v.exists()):
|
||||
if v == '' or v is None or (isinstance(field, forms.FileField) and v is False) or (isinstance(v, QuerySet) and not v.exists()):
|
||||
if field.answer.file:
|
||||
field.answer.file.delete()
|
||||
field.answer.delete()
|
||||
|
||||
@@ -60,9 +60,9 @@
|
||||
{% if pos.variation %}
|
||||
– {{ pos.variation }}
|
||||
{% endif %}
|
||||
{% if forloop.counter > 1 %}
|
||||
{% if forms.0.copy_answer_from is not None %}
|
||||
<span class="text-right flip">
|
||||
<button type="button" data-id="{{ forloop.counter0 }}" name="copy" class="js-copy-answers btn btn-default btn-xs">{% trans "Copy answers from above" %}</button>
|
||||
<button type="button" data-id="{{ forms.0.pos.id }}" data-copy-from="{{ forms.0.copy_answer_from }}" name="copy" class="js-copy-answers btn btn-default btn-xs">{% trans "Copy answers from above" %}</button>
|
||||
<i class="fa fa-angle-down collapse-indicator"></i>
|
||||
</span>
|
||||
{% else %}
|
||||
@@ -122,13 +122,13 @@
|
||||
<legend>
|
||||
{% if form.show_copy_answers_to_addon_button %}
|
||||
<span class="pull-right flip">
|
||||
<button type="button" data-id="{{ forloop.parentloop.counter0 }}" data-addonid="{{ forloop.counter0 }}" name="copy" class="js-copy-answers-addon btn btn-default btn-xs">{% trans "Copy answers" %}</button>
|
||||
<button type="button" data-id="{{ forms.0.pos.id }}" data-addonid="{{ forloop.counter0 }}" name="copy" class="js-copy-answers-addon btn btn-default btn-xs">{% trans "Copy answers" %}</button>
|
||||
</span>
|
||||
{% endif %}
|
||||
+ {{ form.pos.item.name }}{% if form.pos.variation %} – {{ form.pos.variation.value }}{% endif %}
|
||||
</legend>
|
||||
{% endif %}
|
||||
<div data-idx="{{ forloop.parentloop.counter0 }}" data-addonidx="{{ forloop.counter0 }}">
|
||||
<div data-idx="{{ forms.0.pos.id }}" data-addonidx="{{ forloop.counter0 }}">
|
||||
{% bootstrap_form form layout="checkout" %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
@@ -16,9 +16,13 @@ function ngettext(singular, plural, count) {
|
||||
|
||||
function interpolate(fmt, object, named) {
|
||||
if (named) {
|
||||
return fmt.replace(/%\(\w+\)s/g, function(match){return String(obj[match.slice(2,-2)])});
|
||||
return fmt.replace(/%\(\w+\)s/g, function (match) {
|
||||
return String(obj[match.slice(2, -2)])
|
||||
});
|
||||
} else {
|
||||
return fmt.replace(/%s/g, function(match){return String(obj.shift())});
|
||||
return fmt.replace(/%s/g, function (match) {
|
||||
return String(obj.shift())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,13 +175,13 @@ $(function () {
|
||||
$(".js-copy-answers").click(function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
let idx = $(this).data('id');
|
||||
const addonDivs = $('div[data-idx="' + idx +'"]')
|
||||
const idx = $(this).data('id');
|
||||
const copyFromIdx = $(this).data('copy-from')
|
||||
const addonDivs = $('div[data-idx="' + idx + '"]')
|
||||
addonDivs.each(function (index) {
|
||||
const elements = $(this).find('input, select, textarea');
|
||||
|
||||
const addonIdx = $(this).attr("data-addonidx");
|
||||
const answersDiv = $('div[data-idx="0"][data-addonidx="' + addonIdx + '"]');
|
||||
const addonIdx = $(this).data("addonidx");
|
||||
const answersDiv = $('div[data-idx="' + copyFromIdx + '"][data-addonidx="' + addonIdx + '"]');
|
||||
const answers = answersDiv.find('input, select, textarea');
|
||||
|
||||
copy_answers(elements, answers);
|
||||
@@ -189,7 +193,7 @@ $(function () {
|
||||
e.stopPropagation();
|
||||
const id = $(this).data('id');
|
||||
const addonId = $(this).data('addonid');
|
||||
const addonDiv = $('div[data-idx="' + id +'"][data-addonidx="' + addonId + '"]');
|
||||
const addonDiv = $('div[data-idx="' + id + '"][data-addonidx="' + addonId + '"]');
|
||||
const elements = addonDiv.find('input, select, textarea');
|
||||
const answers = $('*[data-idx="' + id + '"] input, *[data-idx="' + id + '"] select, *[data-idx="' + id + '"] textarea');
|
||||
copy_answers(elements, answers);
|
||||
@@ -249,7 +253,7 @@ $(function () {
|
||||
is_enabled = true;
|
||||
}
|
||||
});
|
||||
$(".input-seat-selection option").each(function() {
|
||||
$(".input-seat-selection option").each(function () {
|
||||
if ($(this).val() && $(this).val() !== "" && $(this).prop('selected')) {
|
||||
is_enabled = true;
|
||||
}
|
||||
@@ -257,7 +261,9 @@ $(function () {
|
||||
}
|
||||
if (!is_enabled && !$(".has-seating").length) {
|
||||
$("#btn-add-to-cart").prop("disabled", !is_enabled).popover({
|
||||
'content': function () { return gettext("Please enter a quantity for one of the ticket types.") },
|
||||
'content': function () {
|
||||
return gettext("Please enter a quantity for one of the ticket types.")
|
||||
},
|
||||
'placement': 'top',
|
||||
'trigger': 'hover focus'
|
||||
});
|
||||
@@ -353,7 +359,9 @@ $(function () {
|
||||
if (counter > curCounter) {
|
||||
return; // Lost race
|
||||
}
|
||||
dependent.find("option").filter(function (t) {return !!$(this).attr("value")}).remove();
|
||||
dependent.find("option").filter(function (t) {
|
||||
return !!$(this).attr("value")
|
||||
}).remove();
|
||||
if (data.data.length > 0) {
|
||||
$.each(data.data, function (k, s) {
|
||||
dependent.append($("<option>").attr("value", s.code).text(s.name));
|
||||
@@ -400,8 +408,7 @@ $(function () {
|
||||
true
|
||||
));
|
||||
}
|
||||
var cancel_fee_slider = $('#cancel-fee-slider').slider({
|
||||
}).on('slide', function () {
|
||||
var cancel_fee_slider = $('#cancel-fee-slider').slider({}).on('slide', function () {
|
||||
cancel_fee_slider_update();
|
||||
}).data('slider');
|
||||
if (cancel_fee_slider) {
|
||||
@@ -417,7 +424,7 @@ $(function () {
|
||||
}
|
||||
|
||||
var local_tz = moment.tz.guess()
|
||||
$("span[data-timezone]").each(function() {
|
||||
$("span[data-timezone]").each(function () {
|
||||
var t = moment.tz($(this).attr("data-time"), $(this).attr("data-timezone"))
|
||||
var tz = moment.tz.zone($(this).attr("data-timezone"))
|
||||
|
||||
@@ -445,39 +452,47 @@ $(function () {
|
||||
});
|
||||
|
||||
function copy_answers(elements, answers) {
|
||||
elements.each(function (index) {
|
||||
elements.each(function (index) {
|
||||
var input = $(this),
|
||||
tagName = input.prop('tagName').toLowerCase(),
|
||||
attributeType = input.attr('type'),
|
||||
suffix = input.attr('name').split('-')[1];
|
||||
|
||||
let a = false;
|
||||
switch (tagName) {
|
||||
case "textarea":
|
||||
input.val(answers.filter("[name$=" + suffix + "]").val());
|
||||
a = answers.filter("[name$=" + suffix + "]");
|
||||
if (a.length) input.val(a.val());
|
||||
break;
|
||||
case "select":
|
||||
input.val(answers.filter("[name$=" + suffix + "]").find(":selected").val()).change();
|
||||
a = answers.filter("[name$=" + suffix + "]").find(":selected");
|
||||
if (a.length) input.val(a.val()).change();
|
||||
break;
|
||||
case "input":
|
||||
switch (attributeType) {
|
||||
case "text":
|
||||
case "number":
|
||||
input.val(answers.filter("[name$=" + suffix + "]").val());
|
||||
a = answers.filter("[name$=" + suffix + "]")
|
||||
if (a.length) input.val(a.val());
|
||||
break;
|
||||
case "checkbox":
|
||||
case "radio":
|
||||
if (input.attr('value')) {
|
||||
input.prop("checked", answers.filter("[name$=" + suffix + "][value=" + input.attr('value') + "]").prop("checked"));
|
||||
a = answers.filter("[name$=" + suffix + "][value=" + input.attr('value') + "]")
|
||||
if (a.length) input.prop("checked", a.prop("checked"));
|
||||
} else {
|
||||
input.prop("checked", answers.filter("[name$=" + suffix + "]").prop("checked"));
|
||||
a = answers.filter("[name$=" + suffix + "]")
|
||||
if (a.length) input.prop("checked", a.prop("checked"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
input.val(answers.filter("[name$=" + suffix + "]").val());
|
||||
a = answers.filter("[name$=" + suffix + "]")
|
||||
if (a.length) input.val(a.val());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
input.val(answers.filter("[name$=" + suffix + "]").val());
|
||||
a = answers.filter("[name$=" + suffix + "]")
|
||||
if (a.length) input.val(a.val());
|
||||
}
|
||||
});
|
||||
questions_toggle_dependent(true);
|
||||
|
||||
Reference in New Issue
Block a user