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 Datenschutzbestimmungen und der
Richtlinie zur Förderung der Communitys 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 Wikipedia:Förderung/Projektplanung).""", '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 Nutzungsbedingungen 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 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 = ''