Browse Source

added the automated mail with the possibility to grant travel costs by link in email

master
alpcentaur 1 year ago
parent
commit
960ec8841c
9 changed files with 138 additions and 10 deletions
  1. +7
    -1
      input/forms.py
  2. +17
    -6
      input/management/commands/sendmails.py
  3. +18
    -0
      input/migrations/0066_email_adult.py
  4. +23
    -0
      input/migrations/0067_travel_project_name_alter_library_type.py
  5. +18
    -0
      input/migrations/0068_travel_hotel.py
  6. +18
    -0
      input/migrations/0069_alter_travel_transport.py
  7. +19
    -0
      input/migrations/0070_alter_travel_project.py
  8. +12
    -2
      input/models.py
  9. +6
    -1
      input/views.py

+ 7
- 1
input/forms.py View File

@ -26,6 +26,7 @@ class ProjectForm(FdbForm):
widgets = {'start': AdminDateWidget(), widgets = {'start': AdminDateWidget(),
'end': AdminDateWidget(),} 'end': AdminDateWidget(),}
class ExternForm(FdbForm): class ExternForm(FdbForm):
choice = ChoiceField(choices=TYPE_CHOICES.items(), widget=RadioSelect, choice = ChoiceField(choices=TYPE_CHOICES.items(), widget=RadioSelect,
@ -39,6 +40,7 @@ class ExternForm(FdbForm):
model = ConcreteExtern model = ConcreteExtern
exclude = ('granted', 'granted_date', 'survey_mail_send', 'service_id', 'survey_mail_date') exclude = ('granted', 'granted_date', 'survey_mail_send', 'service_id', 'survey_mail_date')
INTERN_CHOICES = {'PRO': 'Projektsteckbrief', INTERN_CHOICES = {'PRO': 'Projektsteckbrief',
'HON': 'Ehrenamtsbescheinigung, Akkreditierung oder Redaktionsbestätigung', 'HON': 'Ehrenamtsbescheinigung, Akkreditierung oder Redaktionsbestätigung',
'TRAV': 'Reisekostenerstattung'} 'TRAV': 'Reisekostenerstattung'}
@ -51,11 +53,12 @@ class InternForm(FdbForm):
model = ConcreteVolunteer model = ConcreteVolunteer
exclude = ('granted', 'granted_date', 'survey_mail_send', 'survey_mail_date') exclude = ('granted', 'granted_date', 'survey_mail_send', 'survey_mail_date')
class TravelForm(FdbForm): class TravelForm(FdbForm):
# TODO: add some javascript to show/hide other-field # TODO: add some javascript to show/hide other-field
class Meta: class Meta:
model = Travel model = Travel
exclude = ('granted', 'granted_date', 'survey_mail_send', 'realname', 'email', 'survey_mail_date')
exclude = ('granted', 'granted_date', 'survey_mail_send', 'realname', 'email', 'survey_mail_date', 'project', 'request_url', 'payed_for_hotel_by', 'payed_for_travel_by' )
widgets = {'checkin': AdminDateWidget(), widgets = {'checkin': AdminDateWidget(),
'checkout': AdminDateWidget(),} 'checkout': AdminDateWidget(),}
@ -82,6 +85,7 @@ class CheckForm(FdbForm):
label=format_html("Ich stimme den <a href='{}'>Nutzungsbedingungen</a> zu", label=format_html("Ich stimme den <a href='{}'>Nutzungsbedingungen</a> zu",
NUTZUNGSBEDINGUNGEN)) NUTZUNGSBEDINGUNGEN))
class LiteratureForm(CheckForm): class LiteratureForm(CheckForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@ -115,7 +119,9 @@ class BusinessCardForm(CheckForm):
class Media: class Media:
js = ('dropdown/js/base.js',) js = ('dropdown/js/base.js',)
class ListForm(CheckForm): class ListForm(CheckForm):
class Meta: class Meta:
model = List model = List
fields = ['domain', 'address'] fields = ['domain', 'address']

+ 17
- 6
input/management/commands/sendmails.py View File

@ -4,6 +4,7 @@ import sys
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand, CommandError
from django.template.loader import get_template from django.template.loader import get_template
from django.core.mail import send_mail, BadHeaderError, EmailMessage from django.core.mail import send_mail, BadHeaderError, EmailMessage
from django.core.mail import EmailMultiAlternatives
from django.conf import settings from django.conf import settings
from input.models import Project, Library, HonoraryCertificate, Travel, Email,\ from input.models import Project, Library, HonoraryCertificate, Travel, Email,\
@ -112,7 +113,8 @@ class Command(BaseCommand):
approved_notHappened = Project.objects.filter(status = 'NOT')\ approved_notHappened = Project.objects.filter(status = 'NOT')\
.exclude(end_mail_send = False) .exclude(end_mail_send = False)
mail_template = get_template('input/if_not_of_project_approved.txt')
html_mail_template = get_template('input/if_not_of_project_approved.html')
txt_mail_template = get_template('input/if_not_of_project_approved.txt')
informMail_template = get_template('input/if_end_of_project_orginformed.txt') informMail_template = get_template('input/if_end_of_project_orginformed.txt')
# send the mail to project.email, which would be the mail of the volunteer that filled out the form # send the mail to project.email, which would be the mail of the volunteer that filled out the form
@ -121,11 +123,20 @@ class Command(BaseCommand):
context = {'project': project} context = {'project': project}
context['URLPREFIX'] = settings.URLPREFIX context['URLPREFIX'] = settings.URLPREFIX
try: try:
send_mail('Projektende erreicht',
mail_template.render(context),
IF_EMAIL,
[project.email],
fail_silently=False)
subject, from_email, to = 'Projektende erreicht', IF_EMAIL, project.email
text_content = txt_mail_template.render(context)
html_content = html_mail_template.render(context)
msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
msg.attach_alternative(html_content, "text/html")
msg.send()
#send_mail('Projektende erreicht',
# mail_template.render(context),
# IF_EMAIL,
# [project.email],
# fail_silently=False)
send_mail('Projektorganisator*in wurde informiert', send_mail('Projektorganisator*in wurde informiert',
informMail_template.render(context), informMail_template.render(context),
IF_EMAIL, IF_EMAIL,

+ 18
- 0
input/migrations/0066_email_adult.py View File

@ -0,0 +1,18 @@
# Generated by Django 4.1.2 on 2022-11-17 11:12
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('input', '0065_alter_literature_selfbuy_and_more'),
]
operations = [
migrations.AddField(
model_name='email',
name='adult',
field=models.CharField(choices=[('TRUE', 'Ich bin volljährig.'), ('FALSE', 'Ich bin noch nicht volljährig.'), ('NONE', 'Nichts ausgewählt')], default='NONE', max_length=10, verbose_name='Volljährigkeit'),
),
]

+ 23
- 0
input/migrations/0067_travel_project_name_alter_library_type.py View File

@ -0,0 +1,23 @@
# Generated by Django 4.1.2 on 2022-11-17 15:41
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('input', '0066_email_adult'),
]
operations = [
migrations.AddField(
model_name='travel',
name='project_name',
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='Projektname:'),
),
migrations.AlterField(
model_name='library',
name='type',
field=models.CharField(choices=[('BIB', '<a href="https://de.wikipedia.org/wiki/Wikipedia:Förderung/Zugang_zu_Fachliteratur#Bibliotheksstipendium" target="_blank" rel="noopener">Bibliotheksstipendium</a>'), ('ELIT', '<a href="https://de.wikipedia.org/wiki/Wikipedia:Förderung/Zugang_zu_Fachliteratur#eLiteraturstipendium" target="_blank" rel="noopener">eLiteraturstipendium</a>'), ('MAIL', '<a href="https://de.wikipedia.org/wiki/Wikipedia:Förderung/E-Mail-Adressen_und_Visitenkarten#E-Mail-Adressen" target="_blank" rel="noopener">E-Mail-Adresse</a>'), ('IFG', '<a href="https://de.wikipedia.org/wiki/Wikipedia:Förderung/Gebührenerstattungen_für_Behördenanfragen" target="_blank" rel="noopener">Kostenübernahme IFG-Anfrage</a>'), ('LIT', '<a href="https://de.wikipedia.org/wiki/Wikipedia:Förderung/Zugang_zu_Fachliteratur#Literaturstipendium" target="_blank" rel="noopener">Literaturstipendium</a>'), ('LIST', '<a href="https://de.wikipedia.org/wiki/Wikipedia:Förderung/E-Mail-Adressen_und_Visitenkarten#Mailinglisten" target="_blank" rel="noopener">Mailingliste</a>'), ('SOFT', '<a href="https://de.wikipedia.org/wiki/Wikipedia:Förderung/Software-Stipendien" target="_blank" rel="noopener">Softwarestipendium</a>'), ('VIS', '<a href="https://de.wikipedia.org/wiki/Wikipedia:Förderung/E-Mail-Adressen_und_Visitenkarten#Visitenkarten" target="_blank" rel="noopener">Visitenkarten</a>'), ('TRAV', 'Reisekosten')], default='BIB', max_length=4),
),
]

+ 18
- 0
input/migrations/0068_travel_hotel.py View File

@ -0,0 +1,18 @@
# Generated by Django 4.1.2 on 2022-11-17 15:48
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('input', '0067_travel_project_name_alter_library_type'),
]
operations = [
migrations.AddField(
model_name='travel',
name='hotel',
field=models.BooleanField(default=False, verbose_name='Hotelzimmer benötigt:'),
),
]

+ 18
- 0
input/migrations/0069_alter_travel_transport.py View File

@ -0,0 +1,18 @@
# Generated by Django 4.1.2 on 2022-11-17 15:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('input', '0068_travel_hotel'),
]
operations = [
migrations.AlterField(
model_name='travel',
name='transport',
field=models.CharField(choices=[('BAHN', 'Bahn'), ('NONE', 'Keine Fahrtkosten'), ('OTHER', 'Sonstiges (mit Begründung)')], default='BAHN', max_length=5, verbose_name='Transportmittel:'),
),
]

+ 19
- 0
input/migrations/0070_alter_travel_project.py View File

@ -0,0 +1,19 @@
# Generated by Django 4.1.2 on 2022-11-17 16:13
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('input', '0069_alter_travel_transport'),
]
operations = [
migrations.AlterField(
model_name='travel',
name='project',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='input.project'),
),
]

+ 12
- 2
input/models.py View File

@ -144,14 +144,17 @@ PAYEDBY_CHOICES = {'WMDE': 'WMDE',
'REQU': 'Antragstellender Mensch'} 'REQU': 'Antragstellender Mensch'}
class Travel(Intern): class Travel(Intern):
project = models.ForeignKey(Project, on_delete=models.CASCADE)
transport = models.CharField(max_length=5, choices=TRANSPORT_CHOICES.items(), default='BAHN')
# 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 = models.ForeignKey(Project, on_delete=models.CASCADE, null=True, blank=True)
project_name = models.CharField(max_length=50, null=True, blank=True, verbose_name='Projektname:')
transport = models.CharField(max_length=5, choices=TRANSPORT_CHOICES.items(), default='BAHN', verbose_name='Transportmittel:')
other_transport = models.CharField(max_length=200, null=True, blank=True, verbose_name='Sonstige Transportmittel (mit Begründung)') 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") travelcost = models.CharField(max_length=10, default="0", verbose_name="Fahrtkosten")
checkin = models.DateField(blank=True, null=True, verbose_name='Check In') checkin = models.DateField(blank=True, null=True, verbose_name='Check In')
checkout = models.DateField(blank=True, null=True, verbose_name='Check Out') 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_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') payed_for_travel_by = models.CharField(max_length=4, choices=PAYEDBY_CHOICES.items(), blank=True, null=True, verbose_name='Kostenauslage Fahrt durch')
hotel = models.BooleanField(default=False, verbose_name='Hotelzimmer benötigt:')
notes = models.TextField(max_length=1000, blank=True) notes = models.TextField(max_length=1000, blank=True)
@ -174,6 +177,7 @@ TYPE_CHOICES = {'BIB': format_html(' 'LIST': format_html('<a href="https://de.wikipedia.org/wiki/Wikipedia:Förderung/E-Mail-Adressen_und_Visitenkarten#Mailinglisten" target="_blank" rel="noopener">Mailingliste</a>'), 'LIST': format_html('<a href="https://de.wikipedia.org/wiki/Wikipedia:Förderung/E-Mail-Adressen_und_Visitenkarten#Mailinglisten" target="_blank" rel="noopener">Mailingliste</a>'),
'SOFT': format_html('<a href="https://de.wikipedia.org/wiki/Wikipedia:Förderung/Software-Stipendien" target="_blank" rel="noopener">Softwarestipendium</a>'), 'SOFT': format_html('<a href="https://de.wikipedia.org/wiki/Wikipedia:Förderung/Software-Stipendien" target="_blank" rel="noopener">Softwarestipendium</a>'),
'VIS': format_html('<a href="https://de.wikipedia.org/wiki/Wikipedia:Förderung/E-Mail-Adressen_und_Visitenkarten#Visitenkarten" target="_blank" rel="noopener">Visitenkarten</a>'), 'VIS': format_html('<a href="https://de.wikipedia.org/wiki/Wikipedia:Förderung/E-Mail-Adressen_und_Visitenkarten#Visitenkarten" target="_blank" rel="noopener">Visitenkarten</a>'),
'TRAV': format_html('Reisekosten'),
} }
# same model is used for Library, ELitStip and Software! # same model is used for Library, ELitStip and Software!
@ -232,6 +236,11 @@ MAIL_CHOICES = {'REALNAME': 'Vorname.Nachname',
'USERNAME': 'Username', 'USERNAME': 'Username',
'OTHER': 'Sonstiges:'} 'OTHER': 'Sonstiges:'}
ADULT_CHOICES = {'TRUE': format_html('Ich bin volljährig.'),
'FALSE': format_html('Ich bin noch nicht volljährig.'),
'NONE': format_html('Nichts ausgewählt')
}
class Email(Domain): class Email(Domain):
address = models.CharField(max_length=50, address = models.CharField(max_length=50,
choices=MAIL_CHOICES.items(), choices=MAIL_CHOICES.items(),
@ -239,6 +248,7 @@ class Email(Domain):
help_text=format_html("Bitte gib hier den gewünschten Adressbestandteil an,<br>der sich vor der Domain befinden soll.")) help_text=format_html("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='NONE')
class List(Domain): class List(Domain):
address = models.CharField(max_length=50, default='NO_ADDRESS', address = models.CharField(max_length=50, default='NO_ADDRESS',

+ 6
- 1
input/views.py View File

@ -16,7 +16,7 @@ from django.utils.html import format_html
from .forms import ProjectForm, ExternForm, LibraryForm, IFGForm, LiteratureForm,\ from .forms import ProjectForm, ExternForm, LibraryForm, IFGForm, LiteratureForm,\
HonoraryCertificateForm, InternForm, TravelForm, EmailForm,\ HonoraryCertificateForm, InternForm, TravelForm, EmailForm,\
ListForm, BusinessCardForm, INTERN_CHOICES ListForm, BusinessCardForm, INTERN_CHOICES
from .models import Project, TYPE_CHOICES, Library, Literature
from .models import Project, TYPE_CHOICES, Library, Literature, Travel
from .settings import IF_EMAIL from .settings import IF_EMAIL
def auth_deny(choice,pk,auth): def auth_deny(choice,pk,auth):
@ -26,6 +26,8 @@ def auth_deny(choice,pk,auth):
Literature.set_granted(pk,auth) Literature.set_granted(pk,auth)
elif choice == 'IFG': elif choice == 'IFG':
IFG.set_granted(pk,auth) IFG.set_granted(pk,auth)
elif choice == 'TRAV':
Travel.set_granted(pk,auth)
else: else:
return HttpResponse(f'ERROR! UNKNOWN CHOICE TYPE! {choice}') return HttpResponse(f'ERROR! UNKNOWN CHOICE TYPE! {choice}')
return False return False
@ -134,6 +136,7 @@ LABEL_CHOICES = {'BIB': format_html('Bibliothek'),
'LIST': format_html('Mailingliste'), 'LIST': format_html('Mailingliste'),
'SOFT': format_html('Software'), 'SOFT': format_html('Software'),
'VIS': format_html('Visitenkarten'), 'VIS': format_html('Visitenkarten'),
'TRAV': format_html('Reisekosten'),
} }
HELP_CHOICES = {'BIB': format_html("In welchem Zeitraum möchtest du recherchieren oder<br>wie lange ist der Bibliotheksausweis gültig?"), HELP_CHOICES = {'BIB': format_html("In welchem Zeitraum möchtest du recherchieren oder<br>wie lange ist der Bibliotheksausweis gültig?"),
@ -178,6 +181,8 @@ class ExternView(CookieWizardView):
elif choice == 'LIST': elif choice == 'LIST':
form = ListForm(data) form = ListForm(data)
form.fields['domain'].help_text = format_html("Mit welcher Domain, bzw. für welches Wikimedia-Projekt,<br>möchtest du eine Mailingliste beantragen?") form.fields['domain'].help_text = format_html("Mit welcher Domain, bzw. für welches Wikimedia-Projekt,<br>möchtest du eine Mailingliste beantragen?")
elif choice == 'TRAV':
form = TravelForm(data)
else: else:
raise RuntimeError(f'ERROR! UNKNOWN FORMTYPE {choice} in ExternView') raise RuntimeError(f'ERROR! UNKNOWN FORMTYPE {choice} in ExternView')
self.choice = choice self.choice = choice

Loading…
Cancel
Save