chol
/
eva
forked from tohe/eva
1
0
Fork 0

Compare commits

...

37 Commits

Author SHA1 Message Date
Chloe Oltramari f4e05a0799 added first day of employment to email subject 2024-02-05 14:23:53 +01:00
Chloe Oltramari 619b846f3a changed 'Sprache' to 'Sprache im Onboarding' to make its purpose clearer 2024-02-05 14:12:42 +01:00
Chloe Oltramari ab42e76e82 removed Ricarda Busse (DIRECTORAT) from emails sent 2024-02-05 14:10:47 +01:00
Chloe Oltramari b0d1aa1b00 accountMiddleware package needed to be added 2023-10-24 16:38:48 +02:00
Chloe Oltramari f5f10c5414 removed submitter from CCs of all emails. Instead sends one email to submitter with all infos. 2023-10-24 16:35:31 +02:00
Chloe Oltramari b184564c83 added fields landline and add_to_wikimediade 2023-10-24 16:25:48 +02:00
Masin Al-Dujaili a7774f6a41 max_length fix 2023-08-17 13:08:47 +02:00
Masin Al-Dujaili b776c4811b Migrations für vorigen Commit erzeugt 2023-08-11 12:51:51 +02:00
Masin Al-Dujaili ebe3cbedc6 Bereiche umbenannt
Das sollte https://otrs.wikimedia.de/otrs/index.pl?Action=AgentTicketZoom;TicketID=1314485 lösen. Angaben von Jens Behrend.
2023-08-09 15:25:14 +00:00
Masin Al-Dujaili 371cb55544 Austausch Eileen gegen Anna Nölte 2023-04-06 12:29:02 +00:00
Tobias Herre 87e1d6b8f0 Added finance email 2022-05-25 16:06:22 +02:00
Benni Bärmann 1496e3d4b6 changes in production setting 2022-02-09 10:34:51 +01:00
Benni Bärmann c6dabb2213 add translation requirements to README 2022-02-08 12:59:20 +01:00
Benni Bärmann ff1aef386f removed done TODO 2022-02-08 10:57:40 +01:00
Benni Bärmann ad93ab5df1 longer team field 2022-02-08 10:56:46 +01:00
Benni Bärmann 361b6b497c translation of dataloop works now 2022-02-07 14:54:40 +01:00
Benni Bärmann f992d4cc00 mail translation added. test for dataloop translation added (failing) 2022-02-07 12:35:37 +01:00
Benni Bärmann c72b6bd025 translation fixes 2022-01-31 12:08:14 +01:00
Benni Bärmann 19559553b4 additional translations 2022-01-27 20:27:02 +01:00
Benni Bärmann 254ddd2496 translation work 2022-01-27 15:52:27 +01:00
Benni Bärmann 9802446e05 more translation work 2022-01-27 15:46:33 +01:00
Benni Bärmann 40bcae239a some more translation work 2022-01-27 13:36:01 +01:00
Benni Bärmann 22e33327fc added language testing for en (besides en-us) 2022-01-27 13:26:54 +01:00
Benni Bärmann 1cb419f73f in modells we use lazy translation 2022-01-26 15:54:27 +01:00
Benni Bärmann 82dd63a1b5 more translations 2022-01-26 13:29:21 +01:00
Benni Bärmann b94e471ae4 translation working in principle with dev settings 2022-01-25 11:42:13 +01:00
Benni Bärmann aec2fdac16 translation (not working actually) 2022-01-25 11:21:57 +01:00
Benni Bärmann b1b68ae68d added first translation test 2022-01-19 13:36:19 +01:00
Benni Bärmann 76abe007ec added job description to basic data 2021-12-22 10:57:58 +01:00
Benni Bärmann db581e3208 just another TODO change 2021-12-20 16:00:28 +01:00
Benni Bärmann f423f3c6b6 just TODO 2021-12-20 15:51:38 +01:00
Benni Bärmann 594389be0c just some TODO changes 2021-12-15 12:43:56 +01:00
Benni Bärmann 1979dd819b bur removed from TODO 2021-11-17 17:29:57 +01:00
Benni Bärmann 8d997e88f1 bugfix: mobile added to some mails 2021-11-17 16:29:27 +01:00
Benni Bärmann 9434752ebe polution from offboarding branch to master removed 2021-11-17 16:14:30 +01:00
Benni Bärmann b41f624a57 new test in master (?) 2021-11-17 16:12:06 +01:00
Benni Bärmann 4833038eff bugreport added 2021-11-15 12:35:47 +01:00
17 changed files with 432 additions and 77 deletions

View File

@ -7,6 +7,8 @@ meaning "Onboarding, Change, Offboarding"
# development # development
- install gettext for instance via "apt install gettext" for translations
- set up a virtual environment with virtualenvwrapper or some other - set up a virtual environment with virtualenvwrapper or some other
environment managing tool environment managing tool
@ -52,6 +54,7 @@ run the following commands:
python3 manage.py migrate python3 manage.py migrate
python3 manage.py collectstatic python3 manage.py collectstatic
django-admin compilemessages
server starts with server starts with

5
TODO
View File

@ -1,3 +1,8 @@
* switch to django 4
minor stuff:
* remove dot before "Nextcloud" at login page. * remove dot before "Nextcloud" at login page.
* add Testmode warning at login screen * add Testmode warning at login screen

View File

@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/3.1/ref/settings/
""" """
from pathlib import Path from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'. # Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent BASE_DIR = Path(__file__).resolve().parent.parent
@ -58,12 +59,14 @@ MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
] 'allauth.account.middleware.AccountMiddleware'
]
ROOT_URLCONF = 'eva.urls' ROOT_URLCONF = 'eva.urls'
@ -119,7 +122,7 @@ AUTH_PASSWORD_VALIDATORS = [
# Internationalization # Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/ # https://docs.djangoproject.com/en/3.1/topics/i18n/
LANGUAGE_CODE = 'en-us' LANGUAGE_CODE = 'de'
TIME_ZONE = 'UTC' TIME_ZONE = 'UTC'
@ -129,6 +132,7 @@ USE_L10N = True
USE_TZ = True USE_TZ = True
LOCALE_PATHS = ( os.path.join(BASE_DIR, 'locale'), )
# Static files (CSS, JavaScript, Images) # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/ # https://docs.djangoproject.com/en/3.1/howto/static-files/

View File

@ -81,6 +81,7 @@ MIDDLEWARE = [
'whitenoise.middleware.WhiteNoiseMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
@ -141,7 +142,7 @@ AUTH_PASSWORD_VALIDATORS = [
# Internationalization # Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/ # https://docs.djangoproject.com/en/3.1/topics/i18n/
LANGUAGE_CODE = 'en-us' LANGUAGE_CODE = 'de'
TIME_ZONE = 'UTC' TIME_ZONE = 'UTC'
@ -151,6 +152,7 @@ USE_L10N = True
USE_TZ = True USE_TZ = True
LOCALE_PATHS = ( os.path.join(BASE_DIR, 'locale'), )
# Static files (CSS, JavaScript, Images) # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/ # https://docs.djangoproject.com/en/3.1/howto/static-files/

View File

@ -29,7 +29,7 @@ class PersonalForm(EvaForm):
class Meta: class Meta:
model = Employee model = Employee
fields = ['firstname', 'lastname', 'department', 'team', ] fields = ['firstname', 'lastname', 'department', 'team', 'add_to_wikimediade',]
class WorkingForm(EvaForm): class WorkingForm(EvaForm):
@ -57,8 +57,8 @@ class ITForm(EvaForm):
class Meta: class Meta:
model = Employee model = Employee
fields = [ fields = [
'vendor', 'os', 'keyboard', 'screen', 'mobile', 'comment', 'vendor', 'os', 'keyboard', 'screen', 'mobile', 'landline',
'language', 'accounts', 'lists', 'rebu2go' ] 'comment', 'language', 'accounts', 'lists', 'rebu2go' ]
class OfficeForm(EvaForm): class OfficeForm(EvaForm):
class Meta: class Meta:

View File

@ -20,6 +20,7 @@ class Migration(migrations.Migration):
('lastname', models.CharField(max_length=50, verbose_name='Nachname')), ('lastname', models.CharField(max_length=50, verbose_name='Nachname')),
('department', models.CharField(choices=[('PROG', 'Programme'), ('SOFT', 'Softwareentwicklung'), ('CENT', 'Central'), ('VOR', 'Vorstand')], max_length=5, verbose_name='Bereich')), ('department', models.CharField(choices=[('PROG', 'Programme'), ('SOFT', 'Softwareentwicklung'), ('CENT', 'Central'), ('VOR', 'Vorstand')], max_length=5, verbose_name='Bereich')),
('team', models.CharField(blank=True, max_length=20, null=True)), ('team', models.CharField(blank=True, max_length=20, null=True)),
('add_to_wikimediade', models.BooleanField(default=False, verbose_name='Soll auf wikimedia.de irgendwo stehen?')),
('firstdate_employment', models.DateField(null=True, verbose_name='Erster Arbeitstag')), ('firstdate_employment', models.DateField(null=True, verbose_name='Erster Arbeitstag')),
('firstdate_presence', models.DateField(null=True, verbose_name='Erster Tag der Anwesenheit in der Geschäftsstelle')), ('firstdate_presence', models.DateField(null=True, verbose_name='Erster Tag der Anwesenheit in der Geschäftsstelle')),
('jobdescription_german', models.CharField(max_length=100, null=True, verbose_name='Stellenbezeichnung(deutsch)')), ('jobdescription_german', models.CharField(max_length=100, null=True, verbose_name='Stellenbezeichnung(deutsch)')),
@ -30,9 +31,10 @@ class Migration(migrations.Migration):
('os', models.CharField(choices=[('UBU', 'Ubuntu (Standard)'), ('WIN', 'Windows (bitte Begründung angeben)'), ('MOS', 'Mac OS (nur wenn Mac gewählt)')], default='UBU', max_length=3, verbose_name='Betriebssystem')), ('os', models.CharField(choices=[('UBU', 'Ubuntu (Standard)'), ('WIN', 'Windows (bitte Begründung angeben)'), ('MOS', 'Mac OS (nur wenn Mac gewählt)')], default='UBU', max_length=3, verbose_name='Betriebssystem')),
('screen', models.BooleanField(default=False, verbose_name='Zusätzlicher Monitor? Einer ist standard.')), ('screen', models.BooleanField(default=False, verbose_name='Zusätzlicher Monitor? Einer ist standard.')),
('mobile', models.BooleanField(default=False, max_length=6, verbose_name='Diensttelefon (Handy)')), ('mobile', models.BooleanField(default=False, max_length=6, verbose_name='Diensttelefon (Handy)')),
('landline', models.BooleanField(default=False, verbose_name='Festnetznummer (Sipgate)')),
('keyboard', models.CharField(choices=[('DE', 'Deutsch'), ('US', 'USA'), ('OT', 'Anderes (Bitte unten angeben)')], default='DE', max_length=2, verbose_name='Tastaturlayout')), ('keyboard', models.CharField(choices=[('DE', 'Deutsch'), ('US', 'USA'), ('OT', 'Anderes (Bitte unten angeben)')], default='DE', max_length=2, verbose_name='Tastaturlayout')),
('comment', models.TextField(blank=True, max_length=500, null=True, verbose_name='zusätzliche IT-Anforderungen')), ('comment', models.TextField(blank=True, max_length=500, null=True, verbose_name='zusätzliche IT-Anforderungen')),
('language', models.CharField(choices=[('GER', 'Deutsch'), ('ENG', 'English')], default='GER', max_length=3, verbose_name='Sprache')), ('language', models.CharField(choices=[('GER', 'Deutsch'), ('ENG', 'English')], default='GER', max_length=3, verbose_name='Sprache für Onboarding')),
('accounts', multiselectfield.db.fields.MultiSelectField(blank=True, choices=[('OTRSWMDE', 'OTRS Ticketsystem'), ('CIVIC1', 'Civic CRM (allgemein)'), ('CIVIC2', 'Civic CRM (Mailings, impliziert allgemein)'), ('WEB', 'www.wikimedia.de (edit)'), ('BLOG', 'blog.wikimedia.de (edit)'), ('FORUM', 'forum.wikimedia.de')], max_length=37, null=True, verbose_name='Zusätzliche Accounts')), ('accounts', multiselectfield.db.fields.MultiSelectField(blank=True, choices=[('OTRSWMDE', 'OTRS Ticketsystem'), ('CIVIC1', 'Civic CRM (allgemein)'), ('CIVIC2', 'Civic CRM (Mailings, impliziert allgemein)'), ('WEB', 'www.wikimedia.de (edit)'), ('BLOG', 'blog.wikimedia.de (edit)'), ('FORUM', 'forum.wikimedia.de')], max_length=37, null=True, verbose_name='Zusätzliche Accounts')),
('lists', models.CharField(blank=True, max_length=100, null=True, verbose_name='Zusätzliche Mailinglisten')), ('lists', models.CharField(blank=True, max_length=100, null=True, verbose_name='Zusätzliche Mailinglisten')),
('rebu2go', models.BooleanField(default=False, verbose_name='Rebu2Go-Zugang benötigt?')), ('rebu2go', models.BooleanField(default=False, verbose_name='Rebu2Go-Zugang benötigt?')),

View File

@ -0,0 +1,28 @@
# Generated by Django 3.1.4 on 2022-02-08 09:55
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evapp', '0002_auto_20210914_1055'),
]
operations = [
migrations.AlterField(
model_name='employee',
name='department',
field=models.CharField(choices=[('PROG', 'Programme'), ('SOFT', 'Softwareentwicklung'), ('CENT', 'Central'), ('KOMEV', 'Kommunikation und Events'), ('VOR', 'Vorstand')], max_length=5, verbose_name='Bereich'),
),
migrations.AlterField(
model_name='employee',
name='team',
field=models.CharField(blank=True, max_length=50, null=True),
),
migrations.AlterField(
model_name='employee',
name='works_in_gs',
field=models.BooleanField(default=True, verbose_name='Braucht Arbeitsplatz in der Geschäftsstelle?)'),
),
]

View File

@ -0,0 +1,24 @@
# Generated by Django 4.2.4 on 2023-08-11 10:28
from django.db import migrations, models
import multiselectfield.db.fields
class Migration(migrations.Migration):
dependencies = [
('evapp', '0003_auto_20220208_0955'),
]
operations = [
migrations.AlterField(
model_name='employee',
name='accounts',
field=multiselectfield.db.fields.MultiSelectField(blank=True, choices=[('OTRSWMDE', 'OTRS Ticketsystem'), ('CIVIC1', 'Civic CRM (allgemein)'), ('CIVIC2', 'Civic CRM (Mailings, impliziert allgemein)'), ('WEB', 'www.wikimedia.de (edit)'), ('BLOG', 'blog.wikimedia.de (edit)'), ('FORUM', 'forum.wikimedia.de')], max_length=10, null=True, verbose_name='Zusätzliche Accounts'),
),
migrations.AlterField(
model_name='employee',
name='department',
field=models.CharField(choices=[('COENG', 'Communitys & Engagement'), ('SOFT', 'Softwareentwicklung'), ('CENT', 'Central'), ('KOMAD', 'Kommunikation & Advocacy'), ('VOR', 'Vorstand')], max_length=5, verbose_name='Bereich'),
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 4.2.4 on 2023-08-17 11:08
from django.db import migrations
import multiselectfield.db.fields
class Migration(migrations.Migration):
dependencies = [
('evapp', '0004_alter_employee_accounts_alter_employee_department'),
]
operations = [
migrations.AlterField(
model_name='employee',
name='accounts',
field=multiselectfield.db.fields.MultiSelectField(blank=True, choices=[('OTRSWMDE', 'OTRS Ticketsystem'), ('CIVIC1', 'Civic CRM (allgemein)'), ('CIVIC2', 'Civic CRM (Mailings, impliziert allgemein)'), ('WEB', 'www.wikimedia.de (edit)'), ('BLOG', 'blog.wikimedia.de (edit)'), ('FORUM', 'forum.wikimedia.de')], max_length=40, null=True, verbose_name='Zusätzliche Accounts'),
),
]

View File

@ -1,24 +1,25 @@
from django.db import models from django.db import models
from multiselectfield import MultiSelectField from multiselectfield import MultiSelectField
from django.utils.translation import gettext_lazy as _
# ATTENTION!!! # ATTENTION!!!
# No key should be used twice in any of these dicts because of the # No key should be used twice in any of these dicts because of the
# suboptimal implementation in views.EvaFormView.beautify_data() # suboptimal implementation in views.EvaFormView.beautify_data()
# #
DEPARTMENT_CHOICES = {'PROG': 'Programme', DEPARTMENT_CHOICES = {'COENG': _('Communitys & Engagement'),
'SOFT': 'Softwareentwicklung', 'SOFT': _('Softwareentwicklung'),
'CENT': 'Central', 'CENT': 'Central',
'KOMEV': 'Kommunikation und Events', 'KOMAD': _('Kommunikation & Advocacy'),
'VOR': 'Vorstand',} 'VOR': _('Vorstand'),}
VENDOR_CHOICES = {'STANDARD': 'Dell Latitude', VENDOR_CHOICES = {'STANDARD': 'Dell Latitude',
'LENOVO': 'Lenovo Thinkpad', 'LENOVO': 'Lenovo Thinkpad',
'MAC': 'Mac (nur für Grafiker_innen)'} 'MAC': _('Mac (nur für Grafiker_innen)')}
OS_CHOICES = {'UBU': 'Ubuntu (Standard)', OS_CHOICES = {'UBU': 'Ubuntu (Standard)',
'WIN': 'Windows (bitte Begründung angeben)', 'WIN': _('Windows (bitte Begründung angeben)'),
'MOS': 'Mac OS (nur wenn Mac gewählt)'} 'MOS': _('Mac OS (nur wenn Mac gewählt)')}
LANG_CHOICES = {'GER': 'Deutsch', LANG_CHOICES = {'GER': 'Deutsch',
@ -26,19 +27,19 @@ LANG_CHOICES = {'GER': 'Deutsch',
KEYBOARD_CHOICES = {'DE': 'Deutsch', KEYBOARD_CHOICES = {'DE': 'Deutsch',
'US': 'USA', 'US': 'USA',
'OT': 'Anderes (Bitte unten angeben)'} 'OT': _('Anderes (Bitte unten angeben)')}
ACCOUNT_CHOICES = {'OTRSWMDE': 'OTRS Ticketsystem', ACCOUNT_CHOICES = {'OTRSWMDE': 'OTRS Ticketsystem',
'CIVIC1': 'Civic CRM (allgemein)', 'CIVIC1': _('Civic CRM (allgemein)'),
'CIVIC2': "Civic CRM (Mailings, impliziert allgemein)", 'CIVIC2': _("Civic CRM (Mailings, impliziert allgemein)"),
'WEB': 'www.wikimedia.de (edit)', 'WEB': 'www.wikimedia.de (edit)',
'BLOG': 'blog.wikimedia.de (edit)', 'BLOG': 'blog.wikimedia.de (edit)',
'FORUM': 'forum.wikimedia.de', 'FORUM': 'forum.wikimedia.de',
} }
TRANSPONDER_CHOICES = {'NORM': 'Allgemeiner Transponder', TRANSPONDER_CHOICES = {'NORM': _('Allgemeiner Transponder'),
'SPECIAL': 'Besondere Schließungen (bitte angeben)', 'SPECIAL': _('Besondere Schließungen (bitte angeben)'),
'NOTRANS': 'Kein Transponder',} 'NOTRANS': _('Kein Transponder'),}
class Employee(models.Model): class Employee(models.Model):
@ -46,34 +47,36 @@ class Employee(models.Model):
# usermail = models.EmailField(max_length=50, verbose_name="Deine Mailadresse (Ansprechpartner_in)", default='bestechefin@wikimedia.de') # usermail = models.EmailField(max_length=50, verbose_name="Deine Mailadresse (Ansprechpartner_in)", default='bestechefin@wikimedia.de')
# personal data # personal data
firstname = models.CharField(max_length=50, verbose_name="Vorname") firstname = models.CharField(max_length=50, verbose_name=_("Vorname"))
lastname = models.CharField(max_length=50, verbose_name="Nachname") lastname = models.CharField(max_length=50, verbose_name=_("Nachname"))
# intern = models.BooleanField(verbose_name='Interne_r Mitarbeiter_in?', default=True) # intern = models.BooleanField(verbose_name='Interne_r Mitarbeiter_in?', default=True)
department = models.CharField(max_length=5, choices=DEPARTMENT_CHOICES.items(), verbose_name='Bereich') department = models.CharField(max_length=5, choices=DEPARTMENT_CHOICES.items(), verbose_name=_('Bereich'))
team = models.CharField(max_length=20, null=True, blank=True) # TODO? better with choices? team = models.CharField(max_length=50, null=True, blank=True) # TODO? better with choices?
add_to_wikimediade = models.BooleanField(default = False, verbose_name=_('Soll auf wikimedia.de irgendwo stehen?'))
# general work related stuff # general work related stuff
firstdate_employment = models.DateField(null=True, verbose_name="Erster Arbeitstag") firstdate_employment = models.DateField(null=True, verbose_name=_("Erster Arbeitstag"))
firstdate_presence = models.DateField(null=True, verbose_name="Erster Tag der Anwesenheit in der Geschäftsstelle") firstdate_presence = models.DateField(null=True, verbose_name=_("Erster Tag der Anwesenheit in der Geschäftsstelle"))
jobdescription_german = models.CharField(null=True, max_length=100, verbose_name="Stellenbezeichnung(deutsch)") jobdescription_german = models.CharField(null=True, max_length=100, verbose_name="Stellenbezeichnung(deutsch)")
jobdescription_english = models.CharField(null=True, max_length=100, verbose_name="Job description(english)") jobdescription_english = models.CharField(null=True, max_length=100, verbose_name="Job description(english)")
works_in_gs = models.BooleanField(verbose_name='Braucht Arbeitsplatz in der Geschäftsstelle?', default=True) works_in_gs = models.BooleanField(verbose_name=_('Braucht Arbeitsplatz in der Geschäftsstelle?)'), default=True)
desk = models.CharField(max_length=100, null=True, blank=True, verbose_name="Wo soll der Arbeitsplatz sein?") desk = models.CharField(max_length=100, null=True, blank=True, verbose_name=_("Wo soll der Arbeitsplatz sein?"))
# IT related stuff # IT related stuff
vendor = models.CharField(max_length=8, choices=VENDOR_CHOICES.items(), default='STANDARD', verbose_name='Hersteller') vendor = models.CharField(max_length=8, choices=VENDOR_CHOICES.items(), default='STANDARD', verbose_name=_('Hersteller'))
os = models.CharField(max_length=3, choices=OS_CHOICES.items(), default='UBU', verbose_name='Betriebssystem') os = models.CharField(max_length=3, choices=OS_CHOICES.items(), default='UBU', verbose_name=_('Betriebssystem'))
screen = models.BooleanField(default=False, verbose_name='Zusätzlicher Monitor? Einer ist standard.') screen = models.BooleanField(default=False, verbose_name=_('Zusätzlicher Monitor? Einer ist standard.'))
mobile = models.BooleanField(max_length=6, default=False, verbose_name='Diensttelefon (Handy)') mobile = models.BooleanField(max_length=6, default=False, verbose_name=_('Diensttelefon (Handy)'))
landline = models.BooleanField(default = False, verbose_name=_('Festnetznummer (Sipgate)'))
# sim = models.BooleanField(default=False, verbose_name="Mobilfunkvertrag") # sim = models.BooleanField(default=False, verbose_name="Mobilfunkvertrag")
keyboard = models.CharField(max_length=2, choices=KEYBOARD_CHOICES.items(), default='DE', verbose_name="Tastaturlayout") keyboard = models.CharField(max_length=2, choices=KEYBOARD_CHOICES.items(), default='DE', verbose_name=_("Tastaturlayout"))
comment = models.TextField(max_length=500, null=True, blank=True, verbose_name="zusätzliche IT-Anforderungen") comment = models.TextField(max_length=500, null=True, blank=True, verbose_name=_("zusätzliche IT-Anforderungen"))
language = models.CharField(max_length=3, choices=LANG_CHOICES.items(), default="GER", verbose_name="Sprache") language = models.CharField(max_length=3, choices=LANG_CHOICES.items(), default="GER", verbose_name=_("Sprache für Onboarding"))
accounts = MultiSelectField(choices=ACCOUNT_CHOICES.items(), null=True, blank=True, verbose_name="Zusätzliche Accounts") accounts = MultiSelectField(choices=ACCOUNT_CHOICES.items(), max_length=40, null=True, blank=True, verbose_name=_("Zusätzliche Accounts"))
lists = models.CharField(max_length=100, null=True, blank=True, verbose_name="Zusätzliche Mailinglisten") lists = models.CharField(max_length=100, null=True, blank=True, verbose_name=_("Zusätzliche Mailinglisten"))
rebu2go = models.BooleanField(verbose_name="Rebu2Go-Zugang benötigt?", default=False) rebu2go = models.BooleanField(verbose_name=_("Rebu2Go-Zugang benötigt?"), default=False)
# office related stuff # office related stuff
transponder = models.CharField(max_length=7, choices=TRANSPONDER_CHOICES.items(), default='NORM') transponder = models.CharField(max_length=7, choices=TRANSPONDER_CHOICES.items(), default='NORM')
special = models.TextField(max_length=500, null=True, blank=True, verbose_name="Besondere Schließungen hier eintragen") special = models.TextField(max_length=500, null=True, blank=True, verbose_name=_("Besondere Schließungen hier eintragen"))
post_office_box = models.BooleanField(default=True, verbose_name='Postfach am Empfang benötigt?') post_office_box = models.BooleanField(default=True, verbose_name=_('Postfach am Empfang benötigt?'))

View File

@ -5,9 +5,11 @@ ONLY_ONBOARDING = True
EVA_MAIL = 'it-support@wikimedia.de' EVA_MAIL = 'it-support@wikimedia.de'
# these Fields should be included in every mail # these Fields should be included in every mail
BASIC_DATA = ['firstname', 'lastname', 'firstdate_employment', 'firstdate_presence',] BASIC_DATA = ['firstname', 'lastname', 'firstdate_employment', 'firstdate_presence',
'jobdescription_german', 'jobdescription_english',]
# for every department: 'MAIL' => mail adress, 'DATA': additional fields to include # for every department: 'MAIL' => mail adress, 'DATA': additional fields to include
# also one copy with all fields to the person filling the form.
MAILS = { MAILS = {
'IT': { 'IT': {
'MAIL': 'wmde-it@wikimedia.de', 'MAIL': 'wmde-it@wikimedia.de',
@ -20,21 +22,20 @@ MAILS = {
'OFFICE': { 'OFFICE': {
'MAIL': 'office@wikimedia.de', 'MAIL': 'office@wikimedia.de',
'DATA': [ 'DATA': [
'transponder', 'special', 'post_office_box', 'sim', 'sim2', 'transponder', 'special', 'post_office_box', 'mobile',
'works_in_gs', 'desk', 'works_in_gs', 'desk',
], ],
}, },
'KOMM': { 'KOMM': {
'MAIL': 'presse@wikimedia.de', 'MAIL': 'presse@wikimedia.de',
'DATA': [ 'DATA': [
'department', 'team', 'department', 'team', 'add_to_wikimediade'
'jobdescription_german', 'jobdescription_english',
], ],
}, },
'CENTRAL': { 'CENTRAL': {
'MAIL': 'eileen.miedtank@wikimedia.de', 'MAIL': 'anna.noelte@wikimedia.de',
'DATA': [ 'DATA': [
'department', 'team', 'language', 'sim', 'sim2', 'rebu2go' 'department', 'team', 'language', 'mobile', 'rebu2go'
], ],
}, },
'HR': { 'HR': {
@ -43,11 +44,18 @@ MAILS = {
'department', 'team', 'language', 'department', 'team', 'language',
] ]
}, },
'DIRECTORAT': { 'FINANCE': {
'MAIL': 'ricarda.busse@wikimedia.de', 'MAIL': 'claudia.langrock@wikimedia.de',
'DATA': [ 'DATA': [
'team', 'department', 'language', 'rebu2go'
]
},
'SUBMITTER': {
'MAIL': 'submitter@wikimedia.de',
'DATA': [
'department', 'team', 'add_to_wikimediade', 'remote', 'desk', 'vendor',
'os', 'screen', 'mobile', 'landline', 'keyboard', 'comment', 'language',
'accounts', 'lists', 'rebu2go', 'transponder', 'special', 'post_office_box'
] ]
} }
} }

View File

@ -1,4 +1,5 @@
{% load i18n %}
{% autoescape off %} {% autoescape off %}
{% for key, value in data.items %}{% if key == 'laptop' %} {{ key }}: {{ value | safe}}{% else %} {% for key, value in data.items %}{% if key == 'laptop' %} {{ key }}: {{ value | safe}}{% else %}
{{ key }}: {{ value }}{% endif %}{% endfor %} {% trans key %}: {{ value }}{% endif %}{% endfor %}
{% endautoescape %} {% endautoescape %}

View File

@ -1,3 +1,7 @@
{% load i18n %}
(english below)
Hallo! Hallo!
Es gibt einen Neuzugang bei Wikimedia! Hier ( https://wiki.wikimedia.de/wiki/Onboarding ) kannst Du nachsehen, Es gibt einen Neuzugang bei Wikimedia! Hier ( https://wiki.wikimedia.de/wiki/Onboarding ) kannst Du nachsehen,
@ -9,3 +13,19 @@ die Du dafür brauchst:
Wenn Du Fragen hast, melde Dich bei {{contact}}. Wenn Du Fragen hast, melde Dich bei {{contact}}.
Grüße, Deine E.V.A. Grüße, Deine E.V.A.
-------------------------
{% language 'en' %}
Hi!
There is a new employee at Wikimedia! Here ( https://wiki.wikimedia.de/wiki/Onboarding ) you can see, which
steps are now necessary for your department.
All Data you need for this:
{% include 'evapp/dataloop.txt' %}
If you have any questions please write to {{contact}}.
Regards, Your E.V.A.
{% endlanguage %}

View File

@ -14,6 +14,9 @@
{% load socialaccount %} {% load socialaccount %}
{% if user.is_authenticated %} {% if user.is_authenticated %}
{% block content %} {% block content %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<center> <center>
<style> <style>
ul > li { ul > li {
@ -30,22 +33,22 @@
<img src="{% static 'evapp/logo.png' %}" /> <img src="{% static 'evapp/logo.png' %}" />
{% if TESTMODE %} {% if TESTMODE %}
<h1 style="background-color:red;color:white">WARNUNG! Test-MODUS aktiviert. Es werden keine Mails verschickt!</h1> <h1 style="background-color:red;color:white">{% translate "WARNUNG! Test-MODUS aktiviert. Es werden keine Mails verschickt!" %}</h1>
{% endif %} {% endif %}
<h1> <h1>
E (V A) - Eintritt, (Veränderung, Austritt)<p> E (V A) - Eintritt, (Veränderung, Austritt)<p>
</h1>Du bist eingeloggt als {{ user.email }} </h1>{% translate "Du bist eingeloggt als" %} {{ user.email }}
<h2> <h2>
<p>Schritt {{ wizard.steps.step1 }} von {{ wizard.steps.count }}</p> <p> {% translate "Schritt" %} {{ wizard.steps.step1 }} {% translate "von" %} {{ wizard.steps.count }}</p>
<p>{% if wizard.steps.step1 == 1 %} <p>{% if wizard.steps.step1 == 1 %}
Angaben zur Person {% endif %} {% translate "Angaben zur Person" %} {% endif %}
{% if choice == 'IN' %} {% if choice == 'IN' %}
{% if wizard.steps.step1 == 2 %} {% if wizard.steps.step1 == 2 %}
Angaben zum neuen Arbeitsverhältnis {% translate "Angaben zum neuen Arbeitsverhältnis" %}
{% elif wizard.steps.step1 == 3 %} {% elif wizard.steps.step1 == 3 %}
IT-relevante Angaben {% translate "IT-relevante Angaben" %}
{% elif wizard.steps.step1 == 4 %} {% elif wizard.steps.step1 == 4 %}
Office-relevante Angaben {% translate "Office-relevante Angaben" %}
{% endif %} {% endif %}
{% else %} {% else %}
{% if wizard.steps.step1 == 2 %} {% if wizard.steps.step1 == 2 %}
@ -53,7 +56,7 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if datatable == True %} {% if datatable == True %}
Bestätigungsschritt {% translate "Bestätigungsschritt" %}
{% endif %} {% endif %}
</p> </p>
</h2> </h2>
@ -84,21 +87,21 @@
{% endif %} {% endif %}
</table> </table>
<p> <p>
<span style="color: red">*</span> Pflichtfeld <span style="color: red">*</span> {% translate "Pflichtfeld" %}
<p> <p>
{% if wizard.steps.prev %} {% if wizard.steps.prev %}
<button formnovalidate="formnovalidate" name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">Zurück</button> <button formnovalidate="formnovalidate" name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">{% translate "Zurück" %}</button>
{% endif %} {% endif %}
{% if datatable == True %} {% if datatable == True %}
<button type="submit" value="{% trans "Weiter" %}">Abschicken</button> <button type="submit" value="{% trans "Weiter" %}">{% translate "Abschicken" %}</button>
{% else %} {% else %}
<button type="submit" value="{% trans "Weiter" %}">Weiter</button> <button type="submit" value="{% trans "Weiter" %}">{% translate "Weiter" %}</button>
{% endif %} {% endif %}
</form> </form>
<p> <p>
<a href="{% url 'account_logout' %}">logout</a> <a href="{% url 'account_logout' %}">{% translate "logout" %}</a>
</center> </center>
{% endblock %} {% endblock %}
{% else %} {% else %}
<a href="{% provider_login_url 'nextcloud' %}">Bitte einloggen!</a> <a href="{% provider_login_url 'nextcloud' %}">{% translate "Bitte einloggen!" %}</a>
{% endif %} {% endif %}

View File

@ -4,6 +4,7 @@ from django.contrib.auth.models import User
from django.conf import settings from django.conf import settings
from django.http import HttpResponse from django.http import HttpResponse
from django.core import mail from django.core import mail
from django.utils import translation
from .forms import ITForm, WorkingForm, OfficeForm, DummyForm from .forms import ITForm, WorkingForm, OfficeForm, DummyForm
@ -16,6 +17,12 @@ class LoginTestCase(TestCase):
def testLogin(self): def testLogin(self):
self.assertContains(self.response, 'Du bist eingeloggt als vladimir@reiherzehe.com', status_code=200) self.assertContains(self.response, 'Du bist eingeloggt als vladimir@reiherzehe.com', status_code=200)
response_en = self.client.get('/', HTTP_ACCEPT_LANGUAGE='en-us')
self.assertContains(response_en, 'You are logged in as vladimir@reiherzehe.com', status_code=200)
self.assertContains(response_en, 'Firstname', status_code=200)
response_en = self.client.get('/', HTTP_ACCEPT_LANGUAGE='en')
self.assertContains(response_en, 'You are logged in as vladimir@reiherzehe.com', status_code=200)
self.assertContains(response_en, 'Firstname', status_code=200)
def testDebugWarning(self): def testDebugWarning(self):
with self.settings(DEBUG=True): with self.settings(DEBUG=True):
@ -45,8 +52,8 @@ class LoginTestCase(TestCase):
self.assertContains(self.response, 'Programme', status_code=200) self.assertContains(self.response, 'Programme', status_code=200)
self.assertContains(self.response, 'Kommunikation und Events', status_code=200) self.assertContains(self.response, 'Kommunikation und Events', status_code=200)
def testWizzard(self): def test_wizzard_in(self):
''' this test goes through the whole process of the EvaFormView from start to end ''' ''' this test goes through the whole onboarding process of the EvaFormView from start to end '''
self.assertEqual(200, self.response.status_code) self.assertEqual(200, self.response.status_code)
@ -55,6 +62,8 @@ class LoginTestCase(TestCase):
'0-firstname': 'Ara', '0-firstname': 'Ara',
'0-lastname': 'Seva', '0-lastname': 'Seva',
'0-department': 'CENT', '0-department': 'CENT',
'0-team': 'Community Communications',
'0-choice': 'IN',
}, WorkingForm) }, WorkingForm)
response = self._postform({ response = self._postform({
@ -83,10 +92,17 @@ class LoginTestCase(TestCase):
'eva_form_view-current_step': '5', 'eva_form_view-current_step': '5',
}, DummyForm) }, DummyForm)
def test_mail(self): def test_mail(self):
self.testWizzard() self.test_wizzard_in()
# print(mail.outbox) # print(mail.outbox[0].body)
self.assertGreater(len(mail.outbox), 2) self.assertGreater(len(mail.outbox), 2)
self.assertIn("Vorname", mail.outbox[0].body)
self.assertIn("Firstname", mail.outbox[0].body)
for i in (0,1,3):
self.assertIn("Handy", mail.outbox[i].body)
self.assertIn("Ara Seva", mail.outbox[0].subject) self.assertIn("Ara Seva", mail.outbox[0].subject)
class NoLoginTestCase(TestCase): class NoLoginTestCase(TestCase):

View File

@ -10,6 +10,7 @@ from formtools.wizard.views import CookieWizardView
from django.shortcuts import render from django.shortcuts import render
from django.conf import settings from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.utils.translation import gettext_lazy as _
from .models import Employee, DEPARTMENT_CHOICES, OS_CHOICES, VENDOR_CHOICES, \ from .models import Employee, DEPARTMENT_CHOICES, OS_CHOICES, VENDOR_CHOICES, \
LANG_CHOICES, ACCOUNT_CHOICES, TRANSPONDER_CHOICES, KEYBOARD_CHOICES LANG_CHOICES, ACCOUNT_CHOICES, TRANSPONDER_CHOICES, KEYBOARD_CHOICES
@ -28,19 +29,19 @@ def long_process(wizard):
return True return True
else: else:
data = wizard.get_cleaned_data_for_step('0') or {} data = wizard.get_cleaned_data_for_step('0') or {}
print(data) # print(data)
if data.get('choice') != 'CHANGE': if data.get('choice') != 'CHANGE':
wizard.set_choice('IN') wizard.set_choice('IN')
print('PROZESS IN') # print('PROZESS IN')
return True return True
else: else:
wizard.set_choice('CHANGE') wizard.set_choice('CHANGE')
print('PROZESS NOT IN') # print('PROZESS NOT IN')
return False return False
def change_process(wizard): def change_process(wizard):
''' this method is called via urls.py to determine if the form is part of the change process''' ''' this method is called via urls.py to determine if the form is part of the change process'''
print('CHANGE PROZESS') # print('CHANGE PROZESS')
return not long_process(wizard) return not long_process(wizard)
@ -140,21 +141,29 @@ class EvaFormView(LoginRequiredMixin, CookieWizardView):
context = {'data': self.beautify_data(newdata), 'contact': contact} context = {'data': self.beautify_data(newdata), 'contact': contact}
firstname = data['firstname'] firstname = data['firstname']
lastname = data['lastname'] lastname = data['lastname']
firstday = data['firstdate_employment']
try: try:
mail_template = get_template(f'evapp/department_mail.txt') mail_template = get_template(f'evapp/department_mail.txt')
if settings.MAILTEST: if settings.MAILTEST:
send_mail( send_mail(
f'EVA: Neuzugang {firstname} {lastname} (MAILTEST)', f'EVA: Neuzugang {firstname} {lastname} {firstday} (MAILTEST)',
mail_template.render(context), mail_template.render(context),
EVA_MAIL, EVA_MAIL,
[EVA_MAIL, contact], [EVA_MAIL],
fail_silently=False)
elif department != "SUBMITTER":
send_mail(
f'EVA: Neuzugang {firstname} {lastname} {firstday}',
mail_template.render(context),
EVA_MAIL,
[MAILS[department]['MAIL']],
fail_silently=False) fail_silently=False)
else: else:
send_mail( send_mail(
f'EVA: Neuzugang {firstname} {lastname}', f'EVA: Neuzugang {firstname} {lastname} {firstday}',
mail_template.render(context), mail_template.render(context),
EVA_MAIL, EVA_MAIL,
[MAILS[department]['MAIL'], contact], [contact],
fail_silently=False) fail_silently=False)
except BadHeaderError as error: except BadHeaderError as error:
print(error) print(error)

View File

@ -0,0 +1,208 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-07 14:44+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: evapp/models.py:10
msgid "Programme"
msgstr "Programs"
#: evapp/models.py:11
msgid "Softwareentwicklung"
msgstr "Software development"
#: evapp/models.py:13
msgid "Kommunikation und Events"
msgstr "Communication and events"
#: evapp/models.py:14
msgid "Vorstand"
msgstr "Board"
#: evapp/models.py:18
msgid "Mac (nur für Grafiker_innen)"
msgstr "Mac (for graphic designer only)"
#: evapp/models.py:21
msgid "Windows (bitte Begründung angeben)"
msgstr "Windows (please give justification)"
#: evapp/models.py:22
msgid "Mac OS (nur wenn Mac gewählt)"
msgstr "Mac OS (only if you choose Mac)"
#: evapp/models.py:30
msgid "Anderes (Bitte unten angeben)"
msgstr "Others (please note below)"
#: evapp/models.py:33
msgid "Civic CRM (allgemein)"
msgstr "Civic CRM (regular)"
#: evapp/models.py:34
msgid "Civic CRM (Mailings, impliziert allgemein)"
msgstr "Civic CRM (mailings, regular implied)"
#: evapp/models.py:40
msgid "Allgemeiner Transponder"
msgstr "Regular Transponder"
#: evapp/models.py:41
msgid "Besondere Schließungen (bitte angeben)"
msgstr "Special Doors (please note below)"
#: evapp/models.py:42
msgid "Kein Transponder"
msgstr "No transponder"
#: evapp/models.py:50 evapp/templates/evapp/department_mail.txt:26
msgid "Vorname"
msgstr "Firstname"
#: evapp/models.py:51
msgid "Nachname"
msgstr "Lastname"
#: evapp/models.py:53
msgid "Bereich"
msgstr "Department"
#: evapp/models.py:57
msgid "Erster Arbeitstag"
msgstr "First workday"
#: evapp/models.py:58
msgid "Erster Tag der Anwesenheit in der Geschäftsstelle"
msgstr "First day in the office"
#: evapp/models.py:61
msgid "Braucht Arbeitsplatz in der Geschäftsstelle?)"
msgstr "Needs a working place in the office"
#: evapp/models.py:62
msgid "Wo soll der Arbeitsplatz sein?"
msgstr "Where should the desk be?"
#: evapp/models.py:65
msgid "Hersteller"
msgstr "Manufacterer"
#: evapp/models.py:66
msgid "Betriebssystem"
msgstr "Operating system"
#: evapp/models.py:67
msgid "Zusätzlicher Monitor? Einer ist standard."
msgstr "Additional monitor. One is standard."
#: evapp/models.py:68
msgid "Diensttelefon (Handy)"
msgstr "work phone (mobile)"
#: evapp/models.py:70
msgid "Tastaturlayout"
msgstr "Keyboard layout"
#: evapp/models.py:71
msgid "zusätzliche IT-Anforderungen"
msgstr "Additional IT requirements"
#: evapp/models.py:72
msgid "Sprache"
msgstr "Language"
#: evapp/models.py:73
msgid "Zusätzliche Accounts"
msgstr "Additional accounts"
#: evapp/models.py:74
msgid "Zusätzliche Mailinglisten"
msgstr "additional mailing lists"
#: evapp/models.py:75
msgid "Rebu2Go-Zugang benötigt?"
msgstr "Needs Rebu2Go account"
#: evapp/models.py:79
msgid "Besondere Schließungen hier eintragen"
msgstr "Special access for doors"
#: evapp/models.py:80
msgid "Postfach am Empfang benötigt?"
msgstr "Needs mailbox at reception"
#: evapp/templates/evapp/employee_form.html:36
msgid "WARNUNG! Test-MODUS aktiviert. Es werden keine Mails verschickt!"
msgstr "ATTENTION! Test mode activated. No mails will be send."
#: evapp/templates/evapp/employee_form.html:40
msgid "Du bist eingeloggt als"
msgstr "You are logged in as"
#: evapp/templates/evapp/employee_form.html:42
msgid "Schritt"
msgstr "Step"
#: evapp/templates/evapp/employee_form.html:42
msgid "von"
msgstr "from"
#: evapp/templates/evapp/employee_form.html:44
msgid "Angaben zur Person"
msgstr "Personal Data"
#: evapp/templates/evapp/employee_form.html:47
msgid "Angaben zum neuen Arbeitsverhältnis"
msgstr "Details of the employment"
#: evapp/templates/evapp/employee_form.html:49
msgid "IT-relevante Angaben"
msgstr "IT-relevant details"
#: evapp/templates/evapp/employee_form.html:51
msgid "Office-relevante Angaben"
msgstr "Office relevant details"
#: evapp/templates/evapp/employee_form.html:59
msgid "Bestätigungsschritt"
msgstr "Confirmation step"
#: evapp/templates/evapp/employee_form.html:91
msgid "Pflichtfeld"
msgstr "Required field"
#: evapp/templates/evapp/employee_form.html:94
msgid "Zurück"
msgstr "Back"
#: evapp/templates/evapp/employee_form.html:97
#: evapp/templates/evapp/employee_form.html:99
msgid "Weiter"
msgstr "Next"
#: evapp/templates/evapp/employee_form.html:97
msgid "Abschicken"
msgstr "Send"
#: evapp/templates/evapp/employee_form.html:103
msgid "logout"
msgstr "logout"
#: evapp/templates/evapp/employee_form.html:107
msgid "Bitte einloggen!"
msgstr "Please log in!"