Translate questionnaire internal_names in migration (todo: test)

This commit is contained in:
Mira Weller
2026-09-30 21:03:27 +02:00
parent 49ed8419bd
commit 0d99672197
@@ -1,6 +1,7 @@
# Generated by Django 4.2.29 on 2026-03-19 14:24
import json
from collections import namedtuple
from itertools import chain, groupby
from django.db import migrations, models
@@ -10,7 +11,7 @@ from i18nfield.strings import LazyI18nString
import pretix.base.models.base
import pretix.base.models.fields
from pretix.base.i18n import language
FakeQuestion = namedtuple(
'FakeQuestion', 'id question position required'
@@ -43,6 +44,8 @@ def get_fake_questions(settings):
def migrate_questions_forward(apps, schema_editor):
from django.utils.translation import gettext as _, get_supported_language_variant
Event = apps.get_model("pretixbase", "Event")
Item = apps.get_model("pretixbase", "Item")
Question = apps.get_model("pretixbase", "Question")
@@ -50,7 +53,7 @@ def migrate_questions_forward(apps, schema_editor):
QuestionnaireChild = apps.get_model("pretixbase", "QuestionnaireChild")
EventSettingsStore = apps.get_model('pretixbase', 'Event_SettingsStore')
def create_grouped_item_questionnaires(event, children, label_prefix, questionnaire_type):
def create_grouped_item_questionnaires(event, children, label_prefix, questionnaire_type, personalized_items=None):
# group by item, creating a unique questionnaire per item
item_questionnaires = (([t[3] for t in children], item_id) for item_id, children in
groupby(children, key=lambda t: t[0]))
@@ -61,10 +64,16 @@ def migrate_questions_forward(apps, schema_editor):
for children, iterator in merged_questionnaires:
items = [item for _c, item in iterator]
internal_name = label_prefix + ', '.join(str(iname or name) for (id, iname, name) in items)
if all(i.personalized for i in items) and len(items) == len(personalized_items) and questionnaire_type == 'PS':
# if we have a questionnaire for exactly all personalized items, we just call it "Attendee data"
# (same as the default questionnaire for new events)
internal_name = _('Attendee data')
# create questionnaires and children
questionnaire = Questionnaire.objects.create(
event=event, type=questionnaire_type, position=0, all_sales_channels=True,
internal_name=label_prefix + ', '.join(str(iname or name) for (id, iname, name) in items)
internal_name=internal_name
)
questionnaire.items.set([id for (id, iname, name) in items])
deps = {}
@@ -94,52 +103,65 @@ def migrate_questions_forward(apps, schema_editor):
settings = {
setting.key: setting.value for setting in EventSettingsStore.objects.filter(object_id=event.id, key__in=(
'system_question_order', 'attendee_names_asked', 'attendee_names_required', 'attendee_emails_asked', 'attendee_emails_required',
'attendee_company_asked', 'attendee_company_required', 'attendee_addresses_asked', 'attendee_addresses_required',
'attendee_company_asked', 'attendee_company_required', 'attendee_addresses_asked', 'attendee_addresses_required', 'locale',
))
}
with language(get_supported_language_variant(settings.get('locale', 'en'))):
# [P] get all ticket-level questions (user-defined and system provided), along with the products for which they're asked
questions = event.questions.filter(container_type='P')
# get all ticket-level questions (user-defined and system provided), along with the products for which they're asked
questions = event.questions.filter(container_type='P')
children = sorted(chain((
(item, q.position, 0, q)
for q in get_fake_questions(settings)
for item in event.items.filter(personalized=True).values_list('id', 'internal_name', 'name')
), (
(item, q.position, q.id, q)
for q in questions.filter(hidden=False)
for item in q.items.values_list('id', 'internal_name', 'name')
)), key=lambda t: (t[0], t[1]))
# [PS] presale
personalized_items = event.items.filter(personalized=True).values_list('id', 'internal_name', 'name')
children = sorted(chain((
(item, q.position, 0, q)
for q in get_fake_questions(settings)
for item in personalized_items
), (
(item, q.position, q.id, q)
for q in questions.filter(hidden=False, ask_during_checkin=False)
for item in q.items.values_list('id', 'internal_name', 'name')
)), key=lambda t: (t[0], t[1]))
create_grouped_item_questionnaires(event, children, '', 'PS')
create_grouped_item_questionnaires(event, children, '', 'PS', personalized_items)
children = sorted(chain((
(item, q.position, q.id, q)
for q in questions.filter(hidden=True)
for item in q.items.values_list('id', 'internal_name', 'name')
)), key=lambda t: (t[0], t[1]))
# [PC] checkin
children = sorted(chain((
(item, q.position, q.id, q)
for q in questions.filter(ask_during_checkin=True)
for item in q.items.values_list('id', 'internal_name', 'name')
)), key=lambda t: (t[0], t[1]))
create_grouped_item_questionnaires(event, children, 'Hidden questions for ', 'PH')
create_grouped_item_questionnaires(event, children, _('Check-in questions for '), 'PC')
# get all order-level questions
questions = list(event.questions.filter(container_type='O', hidden=False).order_by('position'))
if questions:
# create questionnaires and children
questionnaire = Questionnaire.objects.create(
event=event, type='OS', position=0, all_sales_channels=True,
internal_name='Per-order questions',
)
deps = {}
for position, child in enumerate(questions):
deps[child.id] = QuestionnaireChild.objects.create(
questionnaire=questionnaire,
position=position + 1,
user_datafield=child,
required=child.required,
label=child.question,
help_text=child.help_text,
dependency_question=deps[child.dependency_question.id] if child.dependency_question else None,
dependency_values=child.dependency_values,
# [PH] hidden
children = sorted(chain((
(item, q.position, q.id, q)
for q in questions.filter(hidden=True, ask_during_checkin=False)
for item in q.items.values_list('id', 'internal_name', 'name')
)), key=lambda t: (t[0], t[1]))
create_grouped_item_questionnaires(event, children, _('Hidden questions for '), 'PH')
# [O] get all order-level questions
questions = list(event.questions.filter(container_type='O', hidden=False).order_by('position'))
if questions:
# create questionnaires and children
questionnaire = Questionnaire.objects.create(
event=event, type='OS', position=0, all_sales_channels=True,
internal_name=_('Per-order questions'),
)
deps = {}
for position, child in enumerate(questions):
deps[child.id] = QuestionnaireChild.objects.create(
questionnaire=questionnaire,
position=position + 1,
user_datafield=child,
required=child.required,
label=child.question,
help_text=child.help_text,
dependency_question=deps[child.dependency_question.id] if child.dependency_question else None,
dependency_values=child.dependency_values,
)
def migrate_questions_backward(apps, schema_editor):