foerderbarometer/input/forms.py

386 lines
9.8 KiB
Python
Executable File

from django import forms
from django.conf import settings
from django.contrib.admin.widgets import AdminDateWidget
from django.forms import ModelForm
from django.forms.renderers import DjangoTemplates
from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as trans
from .models import (
Project,
ProjectCategory,
WikimediaProject,
IFG,
Library,
ELiterature,
Software,
Travel,
Email,
Literature,
List,
BusinessCard,
)
class TableFormRenderer(DjangoTemplates):
"""
Set in settings as the default form renderer.
"""
form_template_name = 'django/forms/table.html'
class RadioField(forms.ChoiceField):
widget = forms.RadioSelect
class BaseApplicationForm(ModelForm):
"""
Base form for all external applications.
"""
required_css_class = 'required'
check = forms.BooleanField(
required=True,
label=format_html(
"""Ich stimme den <a href="{}" target="_blank" rel="noopener">Datenschutzbestimmungen</a> und der<br>
<a href="{}" target="_blank" rel="noopener">Richtlinie zur Förderung der Communitys</a> zu.""",
settings.DATAPROTECTION,
settings.FOERDERRICHTLINIEN
),
)
PROJECT_COST_GT_1000_MESSAGE = format_html(
"""Bitte beachte, dass für Projektkosten über 1.000 € ein öffentlicher Projektplan erforderlich
ist (siehe <a href="{0}" target="blank_">Wikipedia:Förderung/Projektplanung)</a>.""",
'https://de.wikipedia.org/wiki/Wikipedia:F%C3%B6rderung/Projektplanung'
)
class BaseProjectForm(ModelForm):
categories = {
'categories': ProjectCategory,
'wikimedia_projects': WikimediaProject,
}
class Media:
js = ('dropdown/js/otrs_link.js', 'js/project-categories.js')
def clean(self):
cleaned_data = ModelForm.clean(self)
if self.errors:
return cleaned_data
for field, model in self.categories.items():
field_other = f'{field}_other'
values = cleaned_data[field]
if model.other in values:
if not cleaned_data[field_other]:
self.add_error(field_other, f'Bitte gib einen Wert an oder deselektiere "{model.OTHER}".')
else:
cleaned_data[field_other] = ''
return cleaned_data
class ProjectForm(BaseProjectForm, BaseApplicationForm):
OPTIONAL_FIELDS = {
'categories_other',
'wikimedia_projects_other',
'page',
'group',
'location',
'insurance',
'notes',
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in set(self.fields) - self.OPTIONAL_FIELDS:
self.fields[field].required = True
class Meta:
model = Project
fields = [
'realname',
'email',
'name',
'description',
'categories',
'categories_other',
'wikimedia_projects',
'wikimedia_projects_other',
'start',
'end',
'participants_estimated',
'page',
'group',
'location',
'cost',
'insurance',
'notes',
]
labels = {
'cost': 'Kosten in Euro',
'insurance': 'Haftpflicht- und Unfallversicherung gewünscht',
'participants_estimated': 'Voraussichtliche Zahl der Teilnehmenden',
}
widgets = {
'start': AdminDateWidget,
'end': AdminDateWidget,
}
class Media:
css = {
'all': ('css/dateFieldNoNowShortcutInTravels.css',)
}
def clean_cost(self):
cost = self.cleaned_data['cost']
if cost > 1000:
raise forms.ValidationError(PROJECT_COST_GT_1000_MESSAGE, code='cost-gt-1000')
return cost
HOTEL_CHOICES = {
'TRUE': mark_safe('Hotelzimmer benötigt'),
'FALSE': mark_safe('Kein Hotelzimmer benötigt'),
}
class TravelForm(BaseApplicationForm):
# TODO: add some javascript to show/hide other-field
hotel = RadioField(label='Hotelzimmer benötigt', choices=HOTEL_CHOICES)
# this is the code, to change required to false if needed
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['project_name'].required = True
self.fields['transport'].required = True
self.fields['travelcost'].required = True
self.fields['travelcost'].initial = None
self.fields['checkin'].required = True
self.fields['checkout'].required = True
self.fields['hotel'].required = True
class Meta:
model = Travel
fields = [
'realname',
'email',
'project_name',
'transport',
'travelcost',
'checkin',
'checkout',
'hotel',
'notes',
]
labels = {
'checkin': 'Datum der Anreise',
'checkout': 'Datum der Abreise',
}
widgets = {
'checkin': AdminDateWidget,
'checkout': AdminDateWidget,
}
class Media:
js = ('dropdown/js/otrs_link.js',)
css = {
'all': ('css/dateFieldNoNowShortcutInTravels.css',)
}
class LibraryForm(BaseApplicationForm):
class Meta:
model = Library
fields = [
'realname',
'email',
'cost',
'library',
'duration',
'notes',
]
labels = {
'cost': 'Kosten in Euro',
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['library'].label = self._meta.model.LIBRARY_LABEL
self.fields['library'].help_text = self._meta.model.LIBRARY_HELP_TEXT
self.fields['duration'].help_text = self._meta.model.DURATION_HELP_TEXT
class ELiteratureForm(LibraryForm):
class Meta(LibraryForm.Meta):
model = ELiterature
class SoftwareForm(LibraryForm):
class Meta(LibraryForm.Meta):
model = Software
class IFGForm(BaseApplicationForm):
class Meta:
model = IFG
fields = [
'realname',
'email',
'cost',
'url',
'notes',
]
class TermsForm(BaseApplicationForm):
terms_accepted_label = 'Ich stimme den <a href="{}">Nutzungsbedingungen</a> zu.'
terms_accepted_url = settings.NUTZUNGSBEDINGUNGEN
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['terms_accepted'].required = True
self.fields['terms_accepted'].label = format_html(self.terms_accepted_label, self.terms_accepted_url)
class LiteratureForm(TermsForm):
terms_accepted_url = settings.NUTZUNGSBEDINGUNGEN_LITERATURSTIPENDIUM
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['selfbuy_give_data'].required = True
class Meta:
model = Literature
fields = [
'realname',
'email',
'cost',
'info',
'source',
'notes',
'selfbuy',
'selfbuy_data',
'selfbuy_give_data',
'terms_accepted',
]
class Media:
js = ('dropdown/js/literature.js',)
def clean(self):
cleaned_data = TermsForm.clean(self)
if self.errors:
return cleaned_data
if cleaned_data['selfbuy'] == 'TRUE':
cleaned_data['selfbuy_data'] = ''
cleaned_data['selfbuy_give_data'] = False
return cleaned_data
for field in 'selfbuy_data', 'selfbuy_give_data':
if not cleaned_data.get('selfbuy_data'):
self.add_error(field, trans('This field is required.'))
return cleaned_data
ADULT_CHOICES = {
'TRUE': mark_safe('Ich bin volljährig.'),
'FALSE': mark_safe('Ich bin noch nicht volljährig.'),
}
class EmailForm(TermsForm):
terms_accepted_url = settings.NUTZUNGSBEDINGUNGEN_EMAIL_SERVICE
# this is the code, to change required to false if needed
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['adult'].required = True
self.fields['other'].required = True
adult = RadioField(label='Volljährigkeit', choices=ADULT_CHOICES)
# TODO: add some javascript to show/hide other-field
class Meta:
model = Email
fields = [
'realname',
'email',
'domain',
'address',
'other',
'adult',
'terms_accepted',
]
class Media:
js = ('dropdown/js/mail.js',)
class BusinessCardForm(TermsForm):
terms_accepted_url = settings.NUTZUNGSBEDINGUNGEN_VISITENKARTEN
# this is the code, to change required to false if needed
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['url_of_pic'].required = True
self.fields['send_data_to_print'].required = True
class Meta:
model = BusinessCard
fields = [
'realname',
'email',
'project',
'data',
'variant',
'url_of_pic',
'send_data_to_print',
'sent_to',
'terms_accepted',
]
class Media:
js = ('dropdown/js/businessCard.js',)
class ListForm(TermsForm):
terms_accepted_url = settings.NUTZUNGSBEDINGUNGEN_MAILINGLISTEN
class Meta:
model = List
fields = [
'realname',
'email',
'domain',
'address',
'terms_accepted',
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['address'].initial = ''