fixed spacing & imports

This commit is contained in:
Oliver Zander 2025-10-15 14:46:28 +02:00
parent 7d1511bb93
commit cf81a45231
2 changed files with 141 additions and 114 deletions

View File

@ -1,10 +1,11 @@
from django import forms
from django.conf import settings from django.conf import settings
from django.forms import ModelForm, ChoiceField, RadioSelect, BooleanField, CharField, EmailField
from django.contrib.admin.widgets import AdminDateWidget from django.contrib.admin.widgets import AdminDateWidget
from django.forms import ModelForm, ChoiceField, RadioSelect, BooleanField, CharField, EmailField
from django.forms.renderers import DjangoTemplates from django.forms.renderers import DjangoTemplates
from django.utils.html import format_html from django.utils.html import format_html
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django import forms
from .models import ProjectRequest, PROJECT_CATEGORIES, WIKIMEDIA_CHOICES from .models import ProjectRequest, PROJECT_CATEGORIES, WIKIMEDIA_CHOICES
from .models import ( from .models import (
@ -90,7 +91,6 @@ class CommonOrderMixin(forms.Form):
class ExternForm(FdbForm): class ExternForm(FdbForm):
choice = ChoiceField(choices=TYPE_CHOICES.items(), widget=RadioSelect, choice = ChoiceField(choices=TYPE_CHOICES.items(), widget=RadioSelect,
label='Was möchtest Du beantragen?') label='Was möchtest Du beantragen?')
@ -103,24 +103,22 @@ class ExternForm(FdbForm):
exclude = ('username', 'granted', 'granted_date', 'survey_mail_send', 'service_id', 'survey_mail_date', 'mail_state') exclude = ('username', 'granted', 'granted_date', 'survey_mail_send', 'service_id', 'survey_mail_date', 'mail_state')
INTERN_CHOICES = {'PRO': 'Projektsteckbrief', INTERN_CHOICES = {
'PRO': 'Projektsteckbrief',
'HON': 'Ehrenamtsbescheinigung, Akkreditierung oder Redaktionsbestätigung', 'HON': 'Ehrenamtsbescheinigung, Akkreditierung oder Redaktionsbestätigung',
'TRAV': 'Reisekostenerstattung'} 'TRAV': 'Reisekostenerstattung',
}
class InternForm(FdbForm): class InternForm(FdbForm):
choice = ChoiceField(choices = INTERN_CHOICES.items(), widget=RadioSelect, choice = ChoiceField(choices=INTERN_CHOICES.items(), widget=RadioSelect,
label = 'Was möchtest Du eingeben?') label='Was möchtest Du eingeben?')
class Meta: class Meta:
model = ConcreteVolunteer model = ConcreteVolunteer
exclude = ('granted', 'granted_date', 'survey_mail_send', 'survey_mail_date', 'mail_state') exclude = ('granted', 'granted_date', 'survey_mail_send', 'survey_mail_date', 'mail_state')
HOTEL_CHOICES = {'TRUE': mark_safe('Hotelzimmer benötigt'),
'FALSE': mark_safe('Kein Hotelzimmer benötigt')
}
class BaseApplicationForm(FdbForm): class BaseApplicationForm(FdbForm):
""" """
Base form for all external applications. Base form for all external applications.
@ -147,9 +145,17 @@ class BaseApplicationForm(FdbForm):
settings.DATAPROTECTION, settings.FOERDERRICHTLINIEN)) settings.DATAPROTECTION, settings.FOERDERRICHTLINIEN))
HOTEL_CHOICES = {
'TRUE': mark_safe('Hotelzimmer benötigt'),
'FALSE': mark_safe('Kein Hotelzimmer benötigt'),
}
class TravelForm(BaseApplicationForm, CommonOrderMixin): class TravelForm(BaseApplicationForm, CommonOrderMixin):
# TODO: add some javascript to show/hide other-field # TODO: add some javascript to show/hide other-field
hotel = ChoiceField(label='Hotelzimmer benötigt:', choices=HOTEL_CHOICES.items(), widget=RadioSelect())
# this is the code, to change required to false if needed # this is the code, to change required to false if needed
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@ -162,11 +168,13 @@ class TravelForm(BaseApplicationForm, CommonOrderMixin):
class Meta: class Meta:
model = Travel model = Travel
exclude = ('granted', 'granted_date', 'survey_mail_send', 'realname', 'email', 'survey_mail_date', 'project', 'request_url', 'payed_for_hotel_by', 'payed_for_travel_by', 'intern_notes', 'mail_state' )
widgets = {'checkin': AdminDateWidget(),
'checkout': AdminDateWidget(),}
fields = ['project_name', 'transport', 'travelcost', 'checkin', 'checkout', 'hotel', 'notes'] fields = ['project_name', 'transport', 'travelcost', 'checkin', 'checkout', 'hotel', 'notes']
hotel = ChoiceField(label='Hotelzimmer benötigt:', choices=HOTEL_CHOICES.items(), widget=RadioSelect()) exclude = ('granted', 'granted_date', 'survey_mail_send', 'realname', 'email', 'survey_mail_date', 'project',
'request_url', 'payed_for_hotel_by', 'payed_for_travel_by', 'intern_notes', 'mail_state')
widgets = {
'checkin': AdminDateWidget,
'checkout': AdminDateWidget,
}
class Media: class Media:
js = ('dropdown/js/otrs_link.js',) js = ('dropdown/js/otrs_link.js',)
@ -208,6 +216,7 @@ class HonoraryCertificateForm(FdbForm):
model = HonoraryCertificate model = HonoraryCertificate
fields = ['request_url', 'project'] fields = ['request_url', 'project']
exclude = ['intern_notes'] exclude = ['intern_notes']
class Media: class Media:
js = ('dropdown/js/otrs_link.js',) js = ('dropdown/js/otrs_link.js',)
@ -242,20 +251,23 @@ class LiteratureForm(BaseApplicationForm, CommonOrderMixin):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields['selfbuy_give_data'].required = True self.fields['selfbuy_give_data'].required = True
class Meta: class Meta:
model = Literature model = Literature
fields = ['cost', 'info', 'source', 'notes', 'selfbuy', 'selfbuy_data', 'selfbuy_give_data', 'terms_accepted'] fields = ['cost', 'info', 'source', 'notes', 'selfbuy', 'selfbuy_data', 'selfbuy_give_data', 'terms_accepted']
exclude = ['intern_notes', 'survey_mail_send', 'mail_state'] exclude = ['intern_notes', 'survey_mail_send', 'mail_state']
class Media: class Media:
js = ('dropdown/js/literature.js',) js = ('dropdown/js/literature.js',)
ADULT_CHOICES = {'TRUE': mark_safe('Ich bin volljährig.'),
'FALSE': mark_safe('Ich bin noch nicht volljährig.') ADULT_CHOICES = {
} 'TRUE': mark_safe('Ich bin volljährig.'),
'FALSE': mark_safe('Ich bin noch nicht volljährig.'),
}
class EmailForm(BaseApplicationForm, CommonOrderMixin): class EmailForm(BaseApplicationForm, CommonOrderMixin):
termstoaccept = settings.NUTZUNGSBEDINGUNGEN_EMAIL_SERVICE termstoaccept = settings.NUTZUNGSBEDINGUNGEN_EMAIL_SERVICE
# this is the code, to change required to false if needed # this is the code, to change required to false if needed
@ -266,20 +278,19 @@ class EmailForm(BaseApplicationForm, CommonOrderMixin):
adult = ChoiceField(label='Volljährigkeit', choices=ADULT_CHOICES.items(), widget=RadioSelect()) adult = ChoiceField(label='Volljährigkeit', choices=ADULT_CHOICES.items(), widget=RadioSelect())
# TODO: add some javascript to show/hide other-field # TODO: add some javascript to show/hide other-field
class Meta: class Meta:
model = Email model = Email
fields = ['domain', 'address', 'other', 'adult', 'terms_accepted'] fields = ['domain', 'address', 'other', 'adult', 'terms_accepted']
exclude = ['intern_notes', 'survey_mail_send', 'mail_state'] exclude = ['intern_notes', 'survey_mail_send', 'mail_state']
class Media: class Media:
js = ('dropdown/js/mail.js',) js = ('dropdown/js/mail.js',)
class BusinessCardForm(BaseApplicationForm, CommonOrderMixin): class BusinessCardForm(BaseApplicationForm, CommonOrderMixin):
termstoaccept = settings.NUTZUNGSBEDINGUNGEN_VISITENKARTEN termstoaccept = settings.NUTZUNGSBEDINGUNGEN_VISITENKARTEN
# this is the code, to change required to false if needed # this is the code, to change required to false if needed
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@ -290,16 +301,18 @@ class BusinessCardForm(BaseApplicationForm, CommonOrderMixin):
model = BusinessCard model = BusinessCard
exclude = ['intern_notes', 'survey_mail_send', 'mail_state'] exclude = ['intern_notes', 'survey_mail_send', 'mail_state']
fields = ['project', 'data', 'variant', 'url_of_pic', 'send_data_to_print', 'sent_to', 'terms_accepted'] fields = ['project', 'data', 'variant', 'url_of_pic', 'send_data_to_print', 'sent_to', 'terms_accepted']
class Media: class Media:
js = ('dropdown/js/businessCard.js',) js = ('dropdown/js/businessCard.js',)
class ListForm(BaseApplicationForm, CommonOrderMixin): class ListForm(BaseApplicationForm, CommonOrderMixin):
termstoaccept = settings.NUTZUNGSBEDINGUNGEN_MAILINGLISTEN termstoaccept = settings.NUTZUNGSBEDINGUNGEN_MAILINGLISTEN
class Meta: class Meta:
model = List model = List
fields = ['domain', 'address', 'terms_accepted'] fields = ['domain', 'address', 'terms_accepted']
exclude = ['intern_notes', 'survey_mail_send','mail_state'] exclude = ['intern_notes', 'survey_mail_send', 'mail_state']
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)

View File

@ -1,15 +1,20 @@
from datetime import date from datetime import date
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.core.validators import MaxValueValidator
from django.db import models from django.db import models
from django.db.models.signals import pre_save
from django.dispatch import receiver
from django.utils.html import format_html from django.utils.html import format_html
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator, MaxValueValidator
EMAIL_STATES = {'NONE': 'noch keine Mail versendet', EMAIL_STATES = {
'NONE': 'noch keine Mail versendet',
'INF': 'die Benachrichtigung zur Projektabschlussmail wurde versendet', 'INF': 'die Benachrichtigung zur Projektabschlussmail wurde versendet',
'CLOSE': 'die Projektabschlussmail wurde versendet', 'CLOSE': 'die Projektabschlussmail wurde versendet',
'END': 'alle automatischen Mails, auch surveyMail, wurden versendet'} 'END': 'alle automatischen Mails, auch surveyMail, wurden versendet',
}
class TermsConsentMixin(models.Model): class TermsConsentMixin(models.Model):
@ -35,7 +40,6 @@ class Volunteer(models.Model):
mail_state = models.CharField(max_length=6, choices=EMAIL_STATES.items(), default='NONE') mail_state = models.CharField(max_length=6, choices=EMAIL_STATES.items(), default='NONE')
survey_mail_send = models.BooleanField(default=False, verbose_name='Keine Umfragemail schicken') survey_mail_send = models.BooleanField(default=False, verbose_name='Keine Umfragemail schicken')
@classmethod @classmethod
def set_granted(cl, key, b): def set_granted(cl, key, b):
obj = cl.objects.get(pk=key) obj = cl.objects.get(pk=key)
@ -47,7 +51,6 @@ class Volunteer(models.Model):
abstract = True abstract = True
class Extern(Volunteer): class Extern(Volunteer):
''' abstract basis class for all data entered by extern volunteers ''' ''' abstract basis class for all data entered by extern volunteers '''
@ -57,7 +60,7 @@ class Extern(Volunteer):
# the following Fields are not supposed to be edited by users # the following Fields are not supposed to be edited by users
service_id = models.CharField(max_length=15, null=True, blank=True) service_id = models.CharField(max_length=15, null=True, blank=True)
def save(self,*args,**kwargs): def save(self, *args, **kwargs):
# we don't call save with args/kwargs to avoid UNIQUE CONSTRAINT errors # we don't call save with args/kwargs to avoid UNIQUE CONSTRAINT errors
# but maybe there is a better solution? # but maybe there is a better solution?
super().save() super().save()
@ -67,18 +70,21 @@ class Extern(Volunteer):
class Meta: class Meta:
abstract = True abstract = True
class ConcreteExtern(Extern): class ConcreteExtern(Extern):
''' needed because we can't initiate abstract base classes in the view''' ''' needed because we can't initiate abstract base classes in the view'''
pass pass
class Account(models.Model): class Account(models.Model):
code = models.CharField('Kostenstelle', max_length=5, default='DEF', code = models.CharField('Kostenstelle', max_length=5, default='DEF', null=False, primary_key=True)
null=False, primary_key = True)
description = models.CharField('Beschreibung', max_length=60, default='NO DESCRIPTION') description = models.CharField('Beschreibung', max_length=60, default='NO DESCRIPTION')
intern_notes = models.TextField(max_length=1000, blank=True, verbose_name='interne Anmerkungen') intern_notes = models.TextField(max_length=1000, blank=True, verbose_name='interne Anmerkungen')
def __str__(self): def __str__(self):
return f'{self.code} {self.description}' return f'{self.code} {self.description}'
class Project(Volunteer): class Project(Volunteer):
end_mail_send = models.BooleanField(default=False, verbose_name='Keine Projektabschlussmail schicken') end_mail_send = models.BooleanField(default=False, verbose_name='Keine Projektabschlussmail schicken')
name = models.CharField(max_length=200, verbose_name='Name des Projekts') name = models.CharField(max_length=200, verbose_name='Name des Projekts')
@ -97,12 +103,11 @@ class Project(Volunteer):
insurance_technic = models.BooleanField(default=False, verbose_name='Technikversicherung Ausland') insurance_technic = models.BooleanField(default=False, verbose_name='Technikversicherung Ausland')
support = models.CharField(max_length=300, blank=True, null=True, verbose_name='Betreuungsperson und Vertretung') support = models.CharField(max_length=300, blank=True, null=True, verbose_name='Betreuungsperson und Vertretung')
cost = models.IntegerField(blank=True, null=True, verbose_name='Kosten') cost = models.IntegerField(blank=True, null=True, verbose_name='Kosten')
account = models.ForeignKey('Account', on_delete=models.CASCADE, null=True, to_field='code', db_constraint = False) account = models.ForeignKey('Account', on_delete=models.CASCADE, null=True, to_field='code', db_constraint=False)
granted_from = models.CharField(max_length=100,null=True,verbose_name='Bewilligt von') granted_from = models.CharField(max_length=100, null=True, verbose_name='Bewilligt von')
notes = models.TextField(max_length=1000,null=True,blank=True,verbose_name='Anmerkungen') notes = models.TextField(max_length=1000, null=True, blank=True, verbose_name='Anmerkungen')
intern_notes = models.TextField(max_length=1000, blank=True, verbose_name='interne Anmerkungen') intern_notes = models.TextField(max_length=1000, blank=True, verbose_name='interne Anmerkungen')
# the following Fields are not supposed to be edited by users # the following Fields are not supposed to be edited by users
pid = models.CharField(max_length=15, null=True, blank=True) pid = models.CharField(max_length=15, null=True, blank=True)
status = models.CharField(max_length=3,choices=(('RUN', 'läuft'),('END','beendet'),('NOT','nicht stattgefunden')),default='RUN') status = models.CharField(max_length=3,choices=(('RUN', 'läuft'),('END','beendet'),('NOT','nicht stattgefunden')),default='RUN')
@ -110,66 +115,59 @@ class Project(Volunteer):
project_of_year = models.IntegerField(default=0) project_of_year = models.IntegerField(default=0)
end_quartal = models.CharField(max_length=15, null=True, blank=True, verbose_name='Quartal Projekt Ende') end_quartal = models.CharField(max_length=15, null=True, blank=True, verbose_name='Quartal Projekt Ende')
def save(self, *args, **kwargs):
def save(self,*args,**kwargs): generate_finance_id = False
generate_finance_id=False
'''we generate the autogenerated fields here''' '''we generate the autogenerated fields here'''
# we don't call save with args/kwargs to avoid UNIQUE CONSTRAINT errors # we don't call save with args/kwargs to avoid UNIQUE CONSTRAINT errors
# but maybe there is a better solution? # but maybe there is a better solution?
if not self.pk: if not self.pk:
print ('NO PK THERE'); print('NO PK THERE')
generate_finance_id=True generate_finance_id = True
super().save() super().save()
else: else:
orig = type(self).objects.get(pk=self.pk) # Originaldaten aus der DB abrufen orig = type(self).objects.get(pk=self.pk) # Originaldaten aus der DB abrufen
if orig.start.year != self.start.year: if orig.start.year != self.start.year:
generate_finance_id=True generate_finance_id = True
if orig.account.code != self.account.code: if orig.account.code != self.account.code:
if str(self.account.code) == '21111': if str(self.account.code) == '21111':
generate_finance_id=True generate_finance_id = True
else: else:
self.finance_id = str(self.account.code) self.finance_id = str(self.account.code)
if generate_finance_id: if generate_finance_id:
print ('MUST GENERATE FINANCE ID') print('MUST GENERATE FINANCE ID')
year = self.start.year year = self.start.year
projects = Project.objects.filter(start__year=year) projects = Project.objects.filter(start__year=year)
if not projects: if not projects:
self.project_of_year = 1 self.project_of_year = 1
#self.pid = str(self.start.year) + '-' + str(self.account.code) + str(self.project_of_year).zfill(3) # self.pid = str(self.start.year) + '-' + str(self.account.code) + str(self.project_of_year).zfill(3)
else: else:
# get the project of year number of latest entry # get the project of year number of latest entry
projects = projects.order_by('-project_of_year')[0] projects = projects.order_by('-project_of_year')[0]
# add one to value of latest entry # add one to value of latest entry
self.project_of_year = int(projects.project_of_year) + 1 self.project_of_year = int(projects.project_of_year) + 1
# self.pid = str(self.start.year) + '-' + str(self.account.code) + str(self.project_of_year).zfill(3) # self.pid = str(self.start.year) + '-' + str(self.account.code) + str(self.project_of_year).zfill(3)
if str(self.account.code) == '21111': if str(self.account.code) == '21111':
self.finance_id = str(self.account.code) + '-' + str(self.project_of_year).zfill(3) self.finance_id = str(self.account.code) + '-' + str(self.project_of_year).zfill(3)
else: else:
self.finance_id = str(self.account.code) self.finance_id = str(self.account.code)
# print (('Current PID',self.pid)) # print (('Current PID',self.pid))
if not self.pid: if not self.pid:
self.pid = str(self.account.code) + str(self.pk).zfill(8) self.pid = str(self.account.code) + str(self.pk).zfill(8)
# self.pid = str(self.account.code) + str(self.pk).zfill(3) # self.pid = str(self.account.code) + str(self.pk).zfill(3)
print (('Hallo Leute! Ich save jetzt mal MIT PID DANN!!!',self.pid)) print(('Hallo Leute! Ich save jetzt mal MIT PID DANN!!!', self.pid))
if self.end: if self.end:
self.end_quartal = f'Q{self.end.month // 4 + 1}' self.end_quartal = f'Q{self.end.month // 4 + 1}'
super().save() super().save()
def __str__(self): def __str__(self):
return f'{self.pid} {self.name}' return f'{self.pid} {self.name}'
@ -178,33 +176,41 @@ class Intern(Volunteer):
'''abstract base class for data entry from /intern (except Project)''' '''abstract base class for data entry from /intern (except Project)'''
request_url = models.URLField(max_length=2000, verbose_name='Antrag (URL)') request_url = models.URLField(max_length=2000, verbose_name='Antrag (URL)')
intern_notes = models.TextField(max_length=1000, blank=True, verbose_name='interne Anmerkungen') intern_notes = models.TextField(max_length=1000, blank=True, verbose_name='interne Anmerkungen')
class Meta: class Meta:
abstract = True abstract = True
class ConcreteVolunteer(Volunteer): class ConcreteVolunteer(Volunteer):
''' needed because we can't initiate abstract base classes in the view''' ''' needed because we can't initiate abstract base classes in the view'''
pass pass
class HonoraryCertificate(Intern): class HonoraryCertificate(Intern):
''' this class is also used for accreditations ''' ''' this class is also used for accreditations '''
project = models.ForeignKey(Project, null=True, blank=True, on_delete=models.SET_NULL) project = models.ForeignKey(Project, null=True, blank=True, on_delete=models.SET_NULL)
def __str__(self): def __str__(self):
return 'Certificate for ' + self.realname return 'Certificate for ' + self.realname
TRANSPORT_CHOICES = {'BAHN': 'Bahn', TRANSPORT_CHOICES = {
'BAHN': 'Bahn',
'NONE': 'Keine Fahrtkosten', 'NONE': 'Keine Fahrtkosten',
'OTHER': 'Sonstiges (mit Begründung)'} 'OTHER': 'Sonstiges (mit Begründung)',
}
PAYEDBY_CHOICES = {'WMDE': 'WMDE', PAYEDBY_CHOICES = {
'REQU': 'Antragstellender Mensch'} 'WMDE': 'WMDE',
'REQU': 'Antragstellender Mensch',
}
HOTEL_CHOICES = {'TRUE': mark_safe('Hotelzimmer benötigt'), HOTEL_CHOICES = {
'FALSE': mark_safe('Kein Hotelzimmer benötigt') 'TRUE': mark_safe('Hotelzimmer benötigt'),
} 'FALSE': mark_safe('Kein Hotelzimmer benötigt'),
}
from django.contrib.contenttypes.models import ContentType
class Travel(Extern): class Travel(Extern):
# project variable is now null true and blank true, which means it can be saved without project id to be later on filled out by admins # project variable is now null true and blank true, which means it can be saved without project id to be later on filled out by admins
@ -225,27 +231,15 @@ class Travel(Extern):
# use content type model to get the end date for the project foreign key # use content type model to get the end date for the project foreign key
project_end_quartal = models.CharField(max_length=15, null=True, blank=True, verbose_name='Quartal Projekt Ende') project_end_quartal = models.CharField(max_length=15, null=True, blank=True, verbose_name='Quartal Projekt Ende')
from django.db.models.signals import pre_save
from django.dispatch import receiver
@receiver(pre_save, sender=Travel, dispatch_uid='get_project_end') @receiver(pre_save, sender=Travel, dispatch_uid='get_project_end')
def getProjectEnd(sender, instance, **kwargs): def get_project_end(sender, instance, **kwargs):
#instance.project_end = instance.project.end
if instance.project: if instance.project:
instance.project_end = instance.project.end instance.project_end = instance.project.end
instance.project_end_quartal = instance.project.end_quartal instance.project_end_quartal = instance.project.end_quartal
# using pre save instead
# def save(self,*args,**kwargs):
# '''we generate the autogenerated fields here'''
# # we don't call save with args/kwargs to avoid UNIQUE CONSTRAINT errors
# # but maybe there is a better solution?
# intern_notes
# project_end = self.checkout
# super(Travel, self).save(*args,**kwargs)
#abstract base class for Library and IFG # abstract base class for Library and IFG
class Grant(Extern): class Grant(Extern):
cost = models.CharField(max_length=10, verbose_name='Kosten', cost = models.CharField(max_length=10, verbose_name='Kosten',
help_text='Bitte gib die ungefähr zu erwartenden Kosten in Euro an.') help_text='Bitte gib die ungefähr zu erwartenden Kosten in Euro an.')
@ -291,6 +285,7 @@ TYPE_CHOICES = {
LIBRARY_TYPES = TYPE_BIB, TYPE_ELIT, TYPE_SOFT LIBRARY_TYPES = TYPE_BIB, TYPE_ELIT, TYPE_SOFT
LIBRARY_TYPE_CHOICES = [(choice, TYPE_CHOICES[choice]) for choice in LIBRARY_TYPES] LIBRARY_TYPE_CHOICES = [(choice, TYPE_CHOICES[choice]) for choice in LIBRARY_TYPES]
# same model is used for Library, ELitStip and Software! # same model is used for Library, ELitStip and Software!
class Library(Grant): class Library(Grant):
TYPE = TYPE_BIB TYPE = TYPE_BIB
@ -332,9 +327,10 @@ class Software(Library):
proxy = True proxy = True
SELFBUY_CHOICES = {'TRUE': mark_safe('Ich möchte das Werk selbst kaufen und per Kostenerstattung bei Wikimedia Deutschland abrechnen.'), SELFBUY_CHOICES = {
'TRUE': mark_safe('Ich möchte das Werk selbst kaufen und per Kostenerstattung bei Wikimedia Deutschland abrechnen.'),
'FALSE': mark_safe('Ich möchte, dass Wikimedia Deutschland das Werk für mich kauft'), 'FALSE': mark_safe('Ich möchte, dass Wikimedia Deutschland das Werk für mich kauft'),
} }
class Literature(TermsConsentMixin, Grant): class Literature(TermsConsentMixin, Grant):
@ -351,6 +347,7 @@ class Literature(TermsConsentMixin, Grant):
Telefonnummer, E-Mail-Adresse usw.). Trenne die einzelnen Angaben durch Zeilenumbrüche.')) Telefonnummer, E-Mail-Adresse usw.). Trenne die einzelnen Angaben durch Zeilenumbrüche.'))
intern_notes = models.TextField(max_length=1000, blank=True, verbose_name='interne Anmerkungen') intern_notes = models.TextField(max_length=1000, blank=True, verbose_name='interne Anmerkungen')
class IFG(Grant): class IFG(Grant):
url = models.URLField(max_length=2000, verbose_name='URL', url = models.URLField(max_length=2000, verbose_name='URL',
help_text='Bitte gib den Link zu deiner Anfrage bei Frag den Staat an.') help_text='Bitte gib den Link zu deiner Anfrage bei Frag den Staat an.')
@ -359,11 +356,15 @@ class IFG(Grant):
def __str__(self): def __str__(self):
return 'IFG-Anfrage von ' + self.realname return 'IFG-Anfrage von ' + self.realname
DOMAIN_CHOICES = {'PEDIA': '@wikipedia.de',
DOMAIN_CHOICES = {
'PEDIA': '@wikipedia.de',
'BOOKS': '@wikibooks.de', 'BOOKS': '@wikibooks.de',
'QUOTE': '@wikiquote.de', 'QUOTE': '@wikiquote.de',
'SOURCE': '@wikisource.de', 'SOURCE': '@wikisource.de',
'VERSITY': '@wikiversity.de',} 'VERSITY': '@wikiversity.de',
}
class Domain(Extern): class Domain(Extern):
domain = models.CharField(max_length=10, domain = models.CharField(max_length=10,
@ -373,13 +374,18 @@ class Domain(Extern):
class Meta: class Meta:
abstract = True abstract = True
MAIL_CHOICES = {'REALNAME': 'Vorname.Nachname',
'USERNAME': 'Username',
'OTHER': 'Sonstiges:'}
ADULT_CHOICES = {'TRUE': mark_safe('Ich bin volljährig.'), MAIL_CHOICES = {
'FALSE': mark_safe('Ich bin noch nicht volljährig.') 'REALNAME': 'Vorname.Nachname',
} 'USERNAME': 'Username',
'OTHER': 'Sonstiges:',
}
ADULT_CHOICES = {
'TRUE': mark_safe('Ich bin volljährig.'),
'FALSE': mark_safe('Ich bin noch nicht volljährig.'),
}
class Email(TermsConsentMixin, Domain): class Email(TermsConsentMixin, Domain):
address = models.CharField(max_length=50, address = models.CharField(max_length=50,
@ -387,17 +393,20 @@ class Email(TermsConsentMixin, Domain):
default='USERNAME', verbose_name='Adressbestandteil', default='USERNAME', verbose_name='Adressbestandteil',
help_text=mark_safe('Bitte gib hier den gewünschten Adressbestandteil an,<br>der sich vor der Domain befinden soll.')) help_text=mark_safe('Bitte gib hier den gewünschten Adressbestandteil an,<br>der sich vor der Domain befinden soll.'))
other = models.CharField(max_length=50,blank=True,null=True, verbose_name='Sonstiges') other = models.CharField(max_length=50, blank=True, null=True, verbose_name='Sonstiges')
adult = models.CharField( max_length=10, verbose_name='Volljährigkeit', choices=ADULT_CHOICES.items(), default='FALSE') adult = models.CharField(max_length=10, verbose_name='Volljährigkeit', choices=ADULT_CHOICES.items(), default='FALSE')
intern_notes = models.TextField(max_length=1000, blank=True, verbose_name='interne Anmerkungen') intern_notes = models.TextField(max_length=1000, blank=True, verbose_name='interne Anmerkungen')
class List(TermsConsentMixin, Domain): class List(TermsConsentMixin, Domain):
address = models.CharField(max_length=50, default='NO_ADDRESS', address = models.CharField(max_length=50, default='NO_ADDRESS',
verbose_name='Adressbestandteil für Projektmailingliste', verbose_name='Adressbestandteil für Projektmailingliste',
help_text=mark_safe('Bitte gib hier den gewünschten Adressbestandteil an,<br>der sich vor der Domain befinden soll.')) help_text=mark_safe('Bitte gib hier den gewünschten Adressbestandteil an,<br>der sich vor der Domain befinden soll.'))
intern_notes = models.TextField(max_length=1000, blank=True, verbose_name='interne Anmerkungen') intern_notes = models.TextField(max_length=1000, blank=True, verbose_name='interne Anmerkungen')
PROJECT_CHOICE = {'PEDIA': 'Wikipedia',
PROJECT_CHOICE = {
'PEDIA': 'Wikipedia',
'SOURCE': 'Wikisource', 'SOURCE': 'Wikisource',
'BOOKS': 'Wikibooks', 'BOOKS': 'Wikibooks',
'QUOTE': 'Wikiquote', 'QUOTE': 'Wikiquote',
@ -405,10 +414,14 @@ PROJECT_CHOICE = {'PEDIA': 'Wikipedia',
'VOYAGE': 'Wikivoyage', 'VOYAGE': 'Wikivoyage',
'DATA': 'Wikidata', 'DATA': 'Wikidata',
'NEWS': 'Wikinews', 'NEWS': 'Wikinews',
'COMMONS': 'Wikimedia Commons'} 'COMMONS': 'Wikimedia Commons',
}
BC_VARIANT = {
'PIC': 'mit Bild',
'NOPIC': 'ohne Bild',
}
BC_VARIANT = {'PIC': 'mit Bild',
'NOPIC': 'ohne Bild'}
class BusinessCard(TermsConsentMixin, Extern): class BusinessCard(TermsConsentMixin, Extern):
project = models.CharField(max_length=20, choices=PROJECT_CHOICE.items(), project = models.CharField(max_length=20, choices=PROJECT_CHOICE.items(),
@ -426,7 +439,7 @@ class BusinessCard(TermsConsentMixin, Extern):
variant = models.CharField(max_length=5, choices=BC_VARIANT.items(), variant = models.CharField(max_length=5, choices=BC_VARIANT.items(),
default='NOPIC', verbose_name='Variante', default='NOPIC', verbose_name='Variante',
help_text=mark_safe('so sehen die Varianten aus: <a href="https://upload.wikimedia.org/wikipedia/commons/c/cd/Muster_Visitenkarten_WMDE_2018.jpg">\ help_text=mark_safe('so sehen die Varianten aus: <a href="https://upload.wikimedia.org/wikipedia/commons/c/cd/Muster_Visitenkarten_WMDE_2018.jpg">\
mit Bild</a> <a href="https://upload.wikimedia.org/wikipedia/commons/d/d3/Muster_Visitenkarte_WMDE.png">ohne Bild</a>' )) mit Bild</a> <a href="https://upload.wikimedia.org/wikipedia/commons/d/d3/Muster_Visitenkarte_WMDE.png">ohne Bild</a>'))
url_of_pic = models.CharField(max_length=200, verbose_name='Url des Bildes', default='', help_text='Bitte gib die Wikimedia-Commons-URL des Bildes an.') url_of_pic = models.CharField(max_length=200, verbose_name='Url des Bildes', default='', help_text='Bitte gib die Wikimedia-Commons-URL des Bildes an.')
@ -467,6 +480,7 @@ validate_cost = MaxValueValidator(
), ),
) )
# Application for project funding < 1000 EUR # Application for project funding < 1000 EUR
class ProjectRequest(Volunteer): class ProjectRequest(Volunteer):
name = models.CharField('Name des Projekts', max_length=200) name = models.CharField('Name des Projekts', max_length=200)