2020-10-22 16:02:59 +02:00
from datetime import date
2020-09-21 14:27:16 +02:00
from django . db import models
2020-11-17 10:56:24 +01:00
from django . utils . html import format_html
2020-09-21 14:27:16 +02:00
2020-10-21 13:00:44 +02:00
from . settings import ACCOUNTS
2020-09-22 12:21:05 +02:00
2020-10-22 11:36:16 +02:00
2020-09-30 14:17:38 +02:00
class Volunteer ( models . Model ) :
2020-11-17 16:42:25 +01:00
realname = models . CharField ( max_length = 200 , null = True , verbose_name = " Realname " ,
help_text = " Bitte gib deinen Vornamen und deinen Nachnamen ein. " )
2020-11-17 10:56:24 +01:00
email = models . EmailField ( max_length = 200 , null = True , verbose_name = ' E-Mail-Adresse ' ,
2020-11-17 16:46:32 +01:00
help_text = format_html ( ' Bitte gib deine E-Mail-Adresse ein, damit dich<br>Wikimedia Deutschland bei Rückfragen oder für<br>die Zusage kontaktieren kann. ' ) )
2020-10-22 16:02:59 +02:00
# the following Fields are not supposed to be edited by users
2020-10-20 09:35:04 +02:00
granted = models . BooleanField ( null = True )
2020-10-22 16:02:59 +02:00
granted_date = models . DateField ( null = True )
2020-11-02 11:56:07 +01:00
survey_mail_send = models . BooleanField ( default = False , verbose_name = ' Keine Umfragemail schicken ' )
2021-04-12 13:44:45 +02:00
survey_mail_date = models . DateField ( verbose_name = ' Umfragemail wurde verschickt am ' , null = True , blank = True )
2021-07-06 13:00:34 +02:00
2020-10-20 12:00:59 +02:00
@classmethod
def set_granted ( cl , key , b ) :
obj = cl . objects . get ( pk = key )
obj . granted = b
2020-10-22 16:02:59 +02:00
obj . granted_date = date . today ( )
2020-10-20 12:00:59 +02:00
obj . save ( )
2020-09-30 12:15:58 +02:00
class Meta :
abstract = True
2020-09-30 11:04:47 +02:00
2020-10-22 11:36:16 +02:00
2020-10-26 11:00:12 +01:00
class Extern ( Volunteer ) :
''' abstract basis class for all data entered by extern volunteers '''
2020-11-17 16:42:25 +01:00
username = models . CharField ( max_length = 200 , null = True , verbose_name = ' Benutzer_innenname ' ,
2020-11-17 16:46:32 +01:00
help_text = format_html ( " Bitte gib den Namen ein, mit dem du dich<br>in den Wikimedia-Projekten registriert hast. " ) )
2020-10-26 11:00:12 +01:00
2020-10-29 15:05:11 +01:00
# the following Fields are not supposed to be edited by users
service_id = models . CharField ( max_length = 15 , null = True , blank = True )
def save ( self , * args , * * kwargs ) :
2021-10-07 10:29:04 +02:00
# we don't call save with args/kwargs to avoid UNIQUE CONSTRAINT errors
# but maybe there is a better solution?
2021-10-06 16:15:58 +02:00
super ( ) . save ( )
2020-10-29 15:05:11 +01:00
self . service_id = type ( self ) . __name__ + str ( self . pk )
2021-10-06 16:15:58 +02:00
super ( ) . save ( )
2020-10-29 15:05:11 +01:00
2020-10-26 11:00:12 +01:00
class Meta :
abstract = True
2021-07-06 13:00:34 +02:00
class ConcreteExtern ( Extern ) :
''' needed because we can ' t initiate abstract base classes in the view '''
pass
2021-07-08 08:00:28 +02:00
class Account ( models . Model ) :
code = models . CharField ( ' Kostenstelle ' , max_length = 5 , default = " DEF " ,
null = False , primary_key = True )
description = models . CharField ( ' Beschreibung ' , max_length = 30 , default = ' NO DESCRIPTION ' )
2021-07-07 15:16:39 +02:00
def __str__ ( self ) :
2021-07-08 08:00:28 +02:00
return f " { self . code } { self . description } "
2021-07-07 15:16:39 +02:00
2020-09-30 14:17:38 +02:00
class Project ( Volunteer ) :
2020-11-02 10:58:20 +01:00
name = models . CharField ( max_length = 200 , verbose_name = ' Name des Projekts ' )
description = models . CharField ( max_length = 500 , verbose_name = " Kurzbeschreibung " , null = True )
start = models . DateField ( ' Startdatum ' , null = True , blank = True )
2020-10-21 13:53:39 +02:00
end = models . DateField ( ' Erwartetes Projektende ' , null = True )
2021-04-12 11:48:41 +02:00
otrs = models . URLField ( max_length = 300 , null = True , verbose_name = ' OTRS-Link ' )
plan = models . URLField ( max_length = 2000 , null = True , blank = True , verbose_name = " Link zum Förderplan " )
page = models . URLField ( max_length = 2000 , null = True , blank = True , verbose_name = " Link zur Projektseite " )
2020-11-02 10:58:20 +01:00
urls = models . CharField ( max_length = 2000 , null = True , blank = True , verbose_name = " Weitere Links " )
group = models . CharField ( max_length = 2000 , null = True , blank = True , verbose_name = " Mitorganisierende " )
location = models . CharField ( max_length = 2000 , null = True , blank = True , verbose_name = " Ort/Adresse/Location " )
participants_estimated = models . IntegerField ( blank = True , null = True , verbose_name = ' Teilnehmende angefragt ' )
participants_real = models . IntegerField ( blank = True , null = True , verbose_name = ' Teilnehmende ausgezählt ' )
2020-11-02 11:56:07 +01:00
insurance = models . BooleanField ( default = False , verbose_name = ' Haftpflichtversicherung ' )
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 ' )
cost = models . IntegerField ( blank = True , null = True )
2021-11-01 15:21:25 +01:00
account = models . ForeignKey ( ' Account ' , on_delete = models . CASCADE , null = True , to_field = ' code ' , db_constraint = False )
2020-11-02 11:56:07 +01:00
granted_from = models . CharField ( max_length = 100 , null = True , verbose_name = ' Bewilligt von ' )
notes = models . CharField ( max_length = 1000 , null = True , blank = True , verbose_name = ' Anmerkungen ' )
2020-09-30 11:04:47 +02:00
2020-10-22 16:02:59 +02:00
# the following Fields are not supposed to be edited by users
2020-10-28 15:04:53 +01:00
pid = models . CharField ( max_length = 15 , null = True , blank = True )
2020-10-22 11:36:16 +02:00
end_mail_send = models . BooleanField ( null = True )
2020-10-29 13:14:06 +01:00
status = models . CharField ( max_length = 3 , choices = ( ( ' RUN ' , ' läuft ' ) , ( ' END ' , ' beendet ' ) ) , default = ' RUN ' )
persons = models . IntegerField ( default = 1 )
2021-10-04 10:43:50 +02:00
finance_id = models . CharField ( max_length = 15 , null = True , blank = True )
2021-10-04 12:39:09 +02:00
project_of_year = models . IntegerField ( default = 0 )
2020-11-02 11:56:07 +01:00
2020-10-06 15:15:05 +02:00
def save ( self , * args , * * kwargs ) :
2021-10-04 14:49:18 +02:00
''' we generate the autogenerated fields here '''
2021-10-07 10:29:04 +02:00
# we don't call save with args/kwargs to avoid UNIQUE CONSTRAINT errors
# but maybe there is a better solution?
2021-10-05 10:13:19 +02:00
super ( ) . save ( )
2021-09-30 15:29:50 +02:00
self . pid = str ( self . account . code ) + str ( self . pk ) . zfill ( 3 )
2021-10-07 10:29:04 +02:00
# generation of finance_id
2021-10-04 12:39:09 +02:00
if not self . project_of_year :
2021-10-07 10:29:04 +02:00
# we need to determine if this is a new year with its first new project...
2021-10-04 12:39:09 +02:00
year = self . start . year
2021-10-04 12:57:13 +02:00
projects = Project . objects . filter ( start__year = year )
if not projects :
self . project_of_year = 1
else :
2021-10-04 14:14:01 +02:00
projects = projects . order_by ( " -project_of_year " ) [ 0 ]
self . project_of_year = int ( projects . project_of_year ) + 1
2021-10-04 14:49:18 +02:00
self . finance_id = str ( self . account . code ) + str ( self . project_of_year ) . zfill ( 3 )
2021-10-05 10:13:19 +02:00
super ( ) . save ( )
2020-10-06 15:15:05 +02:00
2020-09-30 11:04:47 +02:00
def __str__ ( self ) :
2020-10-21 13:00:44 +02:00
return f " { self . pid } { self . name } "
2020-09-30 13:31:19 +02:00
2020-10-22 11:36:16 +02:00
2020-10-26 11:38:56 +01:00
class Intern ( Volunteer ) :
''' abstrat base class for data entry from /intern (except Project) '''
2021-04-12 11:48:41 +02:00
request_url = models . URLField ( max_length = 2000 , verbose_name = ' Antrag (URL) ' )
2020-10-26 11:38:56 +01:00
class Meta :
abstract = True
2021-07-07 09:42:51 +02:00
class ConcreteVolunteer ( Volunteer ) :
''' needed because we can ' t initiate abstract base classes in the view '''
pass
2020-10-26 11:38:56 +01:00
class HonoraryCertificate ( Intern ) :
''' this class is also used for accreditations '''
2020-10-26 13:15:38 +01:00
project = models . ForeignKey ( Project , null = True , blank = True , on_delete = models . SET_NULL )
2020-09-30 13:31:19 +02:00
def __str__ ( self ) :
return " Certificate for " + self . realname
2020-09-30 13:46:06 +02:00
2020-10-22 11:36:16 +02:00
2020-11-02 14:04:01 +01:00
TRANSPORT_CHOICES = { ' BAHN ' : ' Bahn ' ,
' NONE ' : ' Keine Fahrtkosten ' ,
' OTHER ' : ' Sonstiges (mit Begründung) ' }
PAYEDBY_CHOICES = { ' WMDE ' : ' WMDE ' ,
' REQU ' : ' Antragstellender Mensch ' }
2020-10-26 11:38:56 +01:00
class Travel ( Intern ) :
2020-10-26 13:15:38 +01:00
project = models . ForeignKey ( Project , on_delete = models . CASCADE )
2020-11-02 14:04:01 +01:00
transport = models . CharField ( max_length = 5 , choices = TRANSPORT_CHOICES . items ( ) , default = ' BAHN ' )
other_transport = models . CharField ( max_length = 200 , null = True , blank = True , verbose_name = ' Sonstige Transportmittel (mit Begründung) ' )
travelcost = models . CharField ( max_length = 10 , default = " 0 " , verbose_name = " Fahrtkosten " )
checkin = models . DateField ( blank = True , null = True , verbose_name = ' Check In ' )
checkout = models . DateField ( blank = True , null = True , verbose_name = ' Check Out ' )
payed_for_hotel_by = models . CharField ( max_length = 4 , choices = PAYEDBY_CHOICES . items ( ) , blank = True , null = True , verbose_name = ' Kostenauslage Hotel durch ' )
payed_for_travel_by = models . CharField ( max_length = 4 , choices = PAYEDBY_CHOICES . items ( ) , blank = True , null = True , verbose_name = ' Kostenauslage Fahrt durch ' )
notes = models . CharField ( max_length = 500 , blank = True )
2020-10-26 11:38:56 +01:00
2020-10-26 11:00:12 +01:00
#abstract base class for Library and IFG
class Grant ( Extern ) :
2020-11-18 16:03:27 +01:00
cost = models . CharField ( max_length = 10 , verbose_name = ' Kosten ' ,
help_text = " Bitte gib die ungefähr zu erwartenden Kosten in Euro an. " )
2020-11-18 16:16:05 +01:00
notes = models . TextField ( max_length = 500 , blank = True , verbose_name = ' Anmerkungen ' ,
help_text = " Bitte gib an wofür Du das Stipendium verwenden willst. " )
2020-09-30 13:46:06 +02:00
2020-09-30 14:17:38 +02:00
class Meta :
abstract = True
2020-10-20 09:35:04 +02:00
2020-11-17 10:56:24 +01:00
TYPE_CHOICES = { ' BIB ' : format_html ( ' <a href= " https://de.wikipedia.org/wiki/Wikipedia:Förderung/Zugang_zu_Fachliteratur#Bibliotheksstipendium " >Bibliotheksstipendium</a> ' ) ,
' ELIT ' : format_html ( ' <a href= " https://de.wikipedia.org/wiki/Wikipedia:Förderung/Zugang_zu_Fachliteratur#eLiteraturstipendium " >eLiteraturstipendium</a> ' ) ,
' MAIL ' : format_html ( ' <a href= " https://de.wikipedia.org/wiki/Wikipedia:Förderung/E-Mail-Adressen_und_Visitenkarten#E-Mail-Adressen " >E-Mail-Adresse</a> ' ) ,
' IFG ' : format_html ( ' <a href= " https://de.wikipedia.org/wiki/Wikipedia:Förderung/Gebührenerstattungen_für_Behördenanfragen " >Kostenübernahme IFG-Anfrage</a> ' ) ,
2020-11-17 13:06:07 +01:00
' LIT ' : format_html ( ' <a href= " https://de.wikipedia.org/wiki/Wikipedia:Förderung/Zugang_zu_Fachliteratur#Literaturstipendium " >Literaturstipendium</a> ' ) ,
' LIST ' : format_html ( ' <a href= " https://de.wikipedia.org/wiki/Wikipedia:Förderung/E-Mail-Adressen_und_Visitenkarten#Mailinglisten " >Mailingliste</a> ' ) ,
' SOFT ' : format_html ( ' <a href= " https://de.wikipedia.org/wiki/Wikipedia:Förderung/Software-Stipendien " >Softwarestipendium</a> ' ) ,
' VIS ' : format_html ( ' <a href= " https://de.wikipedia.org/wiki/Wikipedia:Förderung/E-Mail-Adressen_und_Visitenkarten#Visitenkarten " >Visitenkarten</a> ' ) ,
}
2020-10-19 14:37:51 +02:00
2020-10-20 09:35:04 +02:00
# same model is used for Library, ELitStip and Software!
2020-09-30 14:17:38 +02:00
class Library ( Grant ) :
2020-10-19 13:54:57 +02:00
2020-10-19 11:56:10 +02:00
type = models . CharField (
max_length = 4 ,
2020-10-21 13:27:05 +02:00
choices = TYPE_CHOICES . items ( ) , #attention: actually only BIB, ELIT, SOFT should be used here
2021-10-11 15:50:16 +02:00
default = ' BIB ' ,
2020-10-19 11:56:10 +02:00
)
2020-09-30 14:17:38 +02:00
library = models . CharField ( max_length = 200 )
2020-11-02 14:25:07 +01:00
duration = models . CharField ( max_length = 100 , verbose_name = " Dauer " )
2020-09-30 14:17:38 +02:00
2020-09-30 13:46:06 +02:00
def __str__ ( self ) :
return self . library
2020-09-30 14:17:38 +02:00
2020-10-27 13:47:46 +01:00
class Literature ( Grant ) :
2020-11-18 18:02:23 +01:00
info = models . CharField ( max_length = 500 , verbose_name = ' Informationen zum Werk ' ,
help_text = format_html ( " Bitte gib alle Informationen zum benötigten Werk an,<br> \
die eine eindeutige Identifizierung ermöglichen ( Autor , Titel , Verlag , ISBN , . . . ) " ))
source = models . CharField ( max_length = 200 , verbose_name = ' Bezugsquelle ' ,
help_text = " Bitte gib an, wo du das Werk kaufen möchtest. " )
2020-10-22 11:36:16 +02:00
2020-09-30 14:17:38 +02:00
class IFG ( Grant ) :
2021-04-12 11:48:41 +02:00
url = models . URLField ( max_length = 2000 , verbose_name = " URL " ,
2020-11-18 18:02:23 +01:00
help_text = " Bitte gib den Link zu deiner Anfrage bei Frag den Staat an. " )
2020-09-30 14:17:38 +02:00
def __str__ ( self ) :
return " IFG-Anfrage von " + self . realname
2020-10-27 11:00:58 +01:00
DOMAIN_CHOICES = { ' PEDIA ' : ' @wikipedia.de ' ,
' BOOKS ' : ' @wikibooks.de ' ,
' QUOTE ' : ' @wikiquote.de ' ,
' SOURCE ' : ' @wikisource.de ' ,
' VERSITY ' : ' @wikiversity.de ' , }
class Domain ( Extern ) :
domain = models . CharField ( max_length = 10 ,
choices = DOMAIN_CHOICES . items ( ) ,
default = ' PEDIA ' )
class Meta :
abstract = True
MAIL_CHOICES = { ' REALNAME ' : ' Vorname.Nachname ' ,
' USERNAME ' : ' Username ' ,
' OTHER ' : ' Sonstiges: ' }
class Email ( Domain ) :
2020-10-27 12:37:18 +01:00
address = models . CharField ( max_length = 50 ,
2020-10-27 11:00:58 +01:00
choices = MAIL_CHOICES . items ( ) ,
2020-11-18 17:46:05 +01:00
default = ' USERNAME ' , verbose_name = ' Adressbestandteil ' ,
2020-11-18 18:02:23 +01:00
help_text = format_html ( " Bitte gib hier den gewünschten Adressbestandteil an,<br>der sich vor der Domain befinden soll. " ) )
2020-11-18 17:46:05 +01:00
2020-11-18 18:02:23 +01:00
other = models . CharField ( max_length = 50 , blank = True , null = True , verbose_name = " Sonstiges " )
2020-10-27 11:00:58 +01:00
class List ( Domain ) :
2020-11-18 17:46:05 +01:00
address = models . CharField ( max_length = 50 , default = ' NO_ADDRESS ' ,
verbose_name = " Adressbestandteil für Projektmailingliste " ,
help_text = format_html ( " Bitte gib hier den gewünschten Adressbestandteil an,<br>der sich vor der Domain befinden soll. " ) )
2020-10-27 12:37:18 +01:00
PROJECT_CHOICE = { ' PEDIA ' : ' Wikipedia ' ,
' SOURCE ' : ' Wikisource ' ,
' BOOKS ' : ' Wikibooks ' ,
' QUOTE ' : ' Wikiquote ' ,
' VERSITY ' : ' Wikiversity ' ,
' VOYAGE ' : ' Wikivoyage ' ,
' DATA ' : ' Wikidata ' ,
' NEWS ' : ' Wikinews ' ,
' COMMONS ' : ' Wikimedia Commons ' }
2020-11-18 16:31:55 +01:00
BC_VARIANT = { ' PIC ' : ' mit Bild ' ,
' NOPIC ' : ' ohne Bild ' }
2020-10-27 12:37:18 +01:00
class BusinessCard ( Extern ) :
project = models . CharField ( max_length = 20 , choices = PROJECT_CHOICE . items ( ) ,
2020-11-18 16:24:51 +01:00
default = ' PEDIA ' , verbose_name = ' Wikimedia-Projekt ' ,
help_text = ' Für welches Wikimedia-Projekt möchtest Du Visitenkarten? ' )
data = models . TextField ( max_length = 1000 , verbose_name = ' Persönliche Daten für die Visitenkarten ' , default = ' ' ,
help_text = format_html ( " Bitte gib hier alle persönlichen Daten an, und zwar genau so,<br> \
wie sie ( auch in der entsprechenden Reihenfolge ) auf den Visitenkarten stehen sollen < br > \
( z . B . Vorname Nachname , Benutzer : / Benutzerin : , Benutzer - / - innenname , Anschrift , < br > \
Telefonnummer , E - Mail - Adresse usw . ) . Trenne die einzelnen Angaben durch Zeilenumbrüche . < br > \
Hinweis : Telefonnummern bilden wir üblicherweise im internationalen Format gemäß < br > \
DIN 5008 ab . Als anzugebende E - Mail - Adresse empfehlen wir dir eine Wikimedia - Projekt - < br > \
Adresse , die du ebenfalls beantragen kannst , sofern du nicht bereits eine besitzt . " ))
2020-10-27 12:37:18 +01:00
variant = models . CharField ( max_length = 5 , choices = BC_VARIANT . items ( ) ,
2020-11-18 16:31:55 +01:00
default = ' NOPIC ' , verbose_name = ' Variante ' ,
help_text = format_html ( ' 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 > ' ))
sent_to = models . TextField ( max_length = 1000 , verbose_name = ' Versandadresse ' ,
default = ' ' , help_text = " Bitte gib den Namen und die vollständige Adresse ein, an welche die Visitenkarten geschickt werden sollen. " )