Compare commits

...

4 Commits

1
.gitignore vendored

@ -4,3 +4,4 @@ venv/
db.sqlite3 db.sqlite3
./.DS*/* ./.DS*/*
*/*.sock */*.sock
credentials.yml

@ -12,6 +12,11 @@ https://docs.djangoproject.com/en/5.1/ref/settings/
from pathlib import Path from pathlib import Path
from import_export.formats.base_formats import CSV from import_export.formats.base_formats import CSV
import yaml
# READ YAML FILE
with open('credentials.yml', 'r') as file:
email_creds = yaml.safe_load(file)
IMPORT_FORMATS = [CSV] IMPORT_FORMATS = [CSV]
EXPORT_FORMATS = [CSV] EXPORT_FORMATS = [CSV]
@ -149,6 +154,16 @@ JAZZMIN_SETTINGS = {
"show_ui_builder": True, # Zeigt den UI-Builder im Admin-Bereich "show_ui_builder": True, # Zeigt den UI-Builder im Admin-Bereich
} }
# E-Mail Settings
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = email_creds['EMAIL']['EMAIL_HOST']
EMAIL_PORT = email_creds['EMAIL']['EMAIL_PORT']
EMAIL_USE_SSL = email_creds['EMAIL']['EMAIL_USE_SSL']
EMAIL_HOST_USER = email_creds['EMAIL']['EMAIL_HOST_USER']
EMAIL_HOST_PASSWORD = email_creds['EMAIL']['EMAIL_HOST_PASSWORD']
DEFAULT_FROM_EMAIL = email_creds['EMAIL']['DEFAULT_FROM_EMAIL']
# Admin UI Setting
JAZZMIN_UI_TWEAKS = { JAZZMIN_UI_TWEAKS = {
"navbar_small_text": False, "navbar_small_text": False,
"footer_small_text": False, "footer_small_text": False,

@ -1,11 +1,44 @@
from django import forms from django import forms
from django.contrib import admin from django.contrib import admin, messages
import main.models as MainDB import main.models as MainDB
from datetime import date, datetime from datetime import date, datetime
from django.utils.html import format_html from django.utils.html import format_html
from import_export import resources from import_export import resources
from import_export.admin import ExportMixin, ImportMixin, ImportExportModelAdmin from import_export.admin import ExportMixin, ImportMixin, ImportExportModelAdmin
from django.core.mail import send_mail
from django.template.loader import render_to_string
from django.utils.html import strip_tags
from django.utils.timezone import now
from django.shortcuts import redirect
from django.urls import path
from .models import contributors
# Admin-Action für den Versand der E-Mail
def send_custom_email(modeladmin, request, queryset):
for obj in queryset:
subject = "Helfer - Regionalkongress 2025 "
myVar = [role.name for role in obj.roles.all()]
myVar = myVar[0] if len(myVar) > 0 else "Leer"
html_message = render_to_string("main/email_invite.html", {"firstname": obj.firstname,
"year": obj.birthday.year if obj.birthday != None else "Leer",
"congr": obj.congregation.title if obj.congregation != None else "Leer",
"role": myVar})
plain_message = strip_tags(html_message)
from_email = '"Samuel Zielke" <rk-orga@samuelzielke.de>'
recipient_list = [obj.email]
try:
send_mail(subject, plain_message, from_email, recipient_list, html_message=html_message)
obj.email_sent_at = now()
obj.save()
messages.success(request, f"E-Mail an {obj.email} gesendet.")
except Exception as e:
messages.error(request, f"Fehler beim Senden der E-Mail an {obj.email}: {e}")
send_custom_email.short_description = "Einladungs E-Mail senden"
class contributorsResource(resources.ModelResource): class contributorsResource(resources.ModelResource):
@ -26,6 +59,25 @@ class MainDB_contributorsAdmin(ExportMixin, ImportMixin, admin.ModelAdmin):
search_fields = ('name', 'firstname', 'congregation__title', 'deparment__title', 'mobilnumber', 'email', 'jwpub') search_fields = ('name', 'firstname', 'congregation__title', 'deparment__title', 'mobilnumber', 'email', 'jwpub')
actions = [send_custom_email]
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path('<path:object_id>/send_email/', self.admin_site.admin_view(self.send_email_view), name='send_email')
]
return custom_urls + urls
def send_email_view(self, request, object_id):
obj = self.get_object(request, object_id)
send_custom_email(self, request, [obj])
return redirect(request.META.get('HTTP_REFERER', 'admin:index'))
def email_button(self, obj):
return f'<a class="button" href="send_email/">E-Mail senden</a>'
email_button.allow_tags = True
email_button.short_description = "E-Mail senden"
def get_congregation(self, obj): def get_congregation(self, obj):
return obj.congregation return obj.congregation
get_congregation.short_description = 'Versammlung' get_congregation.short_description = 'Versammlung'

@ -68,7 +68,7 @@ class contributors(models.Model):
firstname = models.CharField(("vorname"), max_length=50) firstname = models.CharField(("vorname"), max_length=50)
birthday = models.DateField(("geburtstag"), auto_now=False, auto_now_add=False, blank=True, null=True) birthday = models.DateField(("geburtstag"), auto_now=False, auto_now_add=False, blank=True, null=True)
congregation = models.ForeignKey("main.congregation", verbose_name=("Versammlung"), on_delete=models.SET_NULL, null=True, blank=True) congregation = models.ForeignKey("main.congregation", verbose_name=("Versammlung"), on_delete=models.SET_NULL, null=True, blank=True)
roles = models.ManyToManyField("main.role", verbose_name=("role"), null=True, blank=True) roles = models.ManyToManyField("main.role", verbose_name=("Vorrecht"), null=True, blank=True)
pioneer = models.BooleanField(("pionier"), default=False) pioneer = models.BooleanField(("pionier"), default=False)
svd = models.BooleanField(("s.v.d."), default=False) svd = models.BooleanField(("s.v.d."), default=False)
gender = models.CharField("Geschlecht",max_length=20, choices=[("M", "Männlich"), ("W", "Weiblich")]) gender = models.CharField("Geschlecht",max_length=20, choices=[("M", "Männlich"), ("W", "Weiblich")])
@ -82,6 +82,7 @@ class contributors(models.Model):
jwpub = models.EmailField(("JWPUB"), max_length=254, null=True, blank=True) jwpub = models.EmailField(("JWPUB"), max_length=254, null=True, blank=True)
notes = models.CharField(("Bemerkung"), max_length=255, null=True, blank=True) notes = models.CharField(("Bemerkung"), max_length=255, null=True, blank=True)
actual = models.BooleanField(("Aktuell"), default=False) actual = models.BooleanField(("Aktuell"), default=False)
email_sent_at = models.DateTimeField(("E-Mail versende"), null=True, blank=True)
class Meta: class Meta:
verbose_name = ("Helfer") verbose_name = ("Helfer")

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Email-Benachrichtigung</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
padding: 20px;
}
.container {
background-color: #ffffff;
padding: 20px;
border-radius: 5px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
}
.button {
display: inline-block;
padding: 10px 20px;
background-color: #007bff;
color: white;
text-decoration: none;
border-radius: 5px;
}
</style>
</head>
<body>
<div class="container">
<h2>Hallo {{ firstname }},</h2>
<p>Die Planungen für den <b>Regionalkongress 2025</b> laufen bereits! Da du uns letztes Jahr großartig unterstützt hast, möchten wir fragen, ob du wieder zur Verfügung stehst.</p>
<p>Bitte gib uns schnellstmöglich eine Rückmeldung, ob und wie du dabei sein kannst.
<br>Du kannst einfach auf diese E-Mail antworten.</p>
<p>Der Aufbau startet am <b>13.08.2025</b>, der Abbau erfolgt nach Programmende am <b>17.08.2025</b>.</p>
<p>Falls sich bei dir etwas unter den Persönlichen Daten geändert hat oder uns fehlt, teile dies uns bitte in deiner Antwort mit.</p>
<p>Wir freuen uns auf dieses besondere Ereignis!</p>
<p>Danke für deine Unterstützung!</p>
<p><b>Persönliche Daten:</b>
<br>
<br><b>Geburtsjahr:</b>{% if year == "Leer" %}<i style="color:red;">Fehlt</i>{% else %}<i style="color:green;">Vorhanden</i>{% endif %}
<br><b>Versammlung:</b>{% if congr == "Leer" %}<i style="color:red;">Fehlt</i>{% else %}<i style="color:green;">Vorhanden</i>{% endif %}
<br><b>Vorrecht:</b>{% if role == "Leer" %}<i style="color:red;">Fehlt</i>{% else %}<i style="color:green;">Vorhanden</i>{% endif %}
</p>
<br>
<p>Mit freundlichen Grüßen,<br><br><b>Samuel Zielke</b><br><br><a href="tel:+49015168825427">0151 68825427</a><br><a href="mailto:rk-orga@samuelzielke.de">rk-orga@samuelzielke.de</a><br></p>
</div>
</body>
</html>
Loading…
Cancel
Save

Powered by TurnKey Linux.