diff --git a/jdav_web/finance/admin.py b/jdav_web/finance/admin.py
index f9a9e2a..d11b233 100644
--- a/jdav_web/finance/admin.py
+++ b/jdav_web/finance/admin.py
@@ -219,7 +219,7 @@ class StatementSubmittedAdmin(admin.ModelAdmin):
messages.error(request,
_("%(name)s is not yet submitted.") % {'name': str(statement)})
return HttpResponseRedirect(reverse('admin:%s_%s_change' % (self.opts.app_label, self.opts.model_name), args=(statement.pk,)))
- if "transaction_execution_confirm" in request.POST:
+ if "transaction_execution_confirm" in request.POST or "transaction_execution_confirm_and_send" in request.POST:
res = statement.confirm(confirmer=get_member(request))
if not res:
# this should NOT happen!
@@ -227,6 +227,9 @@ class StatementSubmittedAdmin(admin.ModelAdmin):
_("An error occured while trying to confirm %(name)s. Please try again.") % {'name': str(statement)})
return HttpResponseRedirect(reverse('admin:%s_%s_overview' % (self.opts.app_label, self.opts.model_name)))
+ if "transaction_execution_confirm_and_send" in request.POST:
+ statement.send_summary(cc=[request.user.member.email] if hasattr(request.user, 'member') else [])
+ messages.success(request, _("Successfully sent receipt to the office."))
messages.success(request,
_("Successfully confirmed %(name)s. I hope you executed the associated transactions, I wont remind you again.")
% {'name': str(statement)})
diff --git a/jdav_web/finance/locale/de/LC_MESSAGES/django.po b/jdav_web/finance/locale/de/LC_MESSAGES/django.po
index df726c6..24fed2d 100644
--- a/jdav_web/finance/locale/de/LC_MESSAGES/django.po
+++ b/jdav_web/finance/locale/de/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2025-04-27 23:00+0200\n"
+"POT-Creation-Date: 2025-05-03 19:06+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -64,6 +64,10 @@ msgstr ""
"Beim Abwickeln von %(name)s ist ein Fehler aufgetreten. Bitte versuche es "
"erneut."
+#: finance/admin.py
+msgid "Successfully sent receipt to the office."
+msgstr "Abrechnungsbeleg an die Geschäftsstelle gesendet."
+
#: finance/admin.py
#, python-format
msgid ""
@@ -283,6 +287,10 @@ msgstr "Abrechnungen"
msgid "Statement: %(excursion)s"
msgstr "Abrechnung: %(excursion)s"
+#: finance/models.py
+msgid "Excursion %(excursion)s"
+msgstr "Ausfahrt %(excursion)s"
+
#: finance/models.py
msgid "Ready to confirm"
msgstr "Bereit zur Abwicklung"
@@ -310,6 +318,11 @@ msgstr "LJP-Zuschuss %(excu)s"
msgid "Total"
msgstr "Gesamtbetrag"
+#: finance/models.py
+#, python-format
+msgid "Statement summary for %(title)s"
+msgstr "Abrechnung für %(title)s"
+
#: finance/models.py
msgid "Statement in preparation"
msgstr "Abrechnung in Vorbereitung"
@@ -433,8 +446,12 @@ msgid "I did execute the listed transactions."
msgstr "Ich habe die aufgeführten Überweisungen ausgeführt."
#: finance/templates/admin/confirmed_statement.html
-msgid "Confirm"
-msgstr "Bestätigen"
+msgid "Confirm only"
+msgstr "Nur bestätigen"
+
+#: finance/templates/admin/confirmed_statement.html
+msgid "Confirm and send receipt to office"
+msgstr "Bestätigen und Beleg an die Geschäftsstelle senden"
#: finance/templates/admin/overview_submitted_statement.html
msgid "Overview"
@@ -558,8 +575,8 @@ msgid ""
"against allowances and subsidies."
msgstr ""
"Da Personen über 27 an der Ausfahrt teilnehommen haben, wird ein "
-"Organisationsbeitrag von %(org_fee)s€ pro Person und Tag fällig. Der Gesamtbetrag "
-"von %(total_org_fee_theoretical)s€ wird mit Zuschüssen und "
+"Organisationsbeitrag von %(org_fee)s€ pro Person und Tag fällig. Der "
+"Gesamtbetrag von %(total_org_fee_theoretical)s€ wird mit Zuschüssen und "
"Aufwandsentschädigungen verrechnet."
#: finance/templates/admin/overview_submitted_statement.html
diff --git a/jdav_web/finance/models.py b/jdav_web/finance/models.py
index 2e4b3e1..c09cf22 100644
--- a/jdav_web/finance/models.py
+++ b/jdav_web/finance/models.py
@@ -15,6 +15,9 @@ import rules
from contrib.models import CommonModel
from contrib.rules import has_global_perm
from utils import cvt_to_decimal, RestrictedFileField
+from members.pdf import render_tex_with_attachments
+from mailer.mailutils import send as send_mail
+from contrib.media import media_path
from schwifty import IBAN
import re
@@ -121,6 +124,13 @@ class Statement(CommonModel):
else:
return self.short_description
+ @property
+ def title(self):
+ if self.excursion is not None:
+ return _('Excursion %(excursion)s') % {'excursion': str(self.excursion)}
+ else:
+ return self.short_description
+
def submit(self, submitter=None):
self.submitted = True
self.submitted_date = timezone.now()
@@ -534,6 +544,23 @@ class Statement(CommonModel):
.order_by('short_description')\
.annotate(amount=Sum('amount'))
+ def send_summary(self, cc=None):
+ """
+ Sends a summary of the statement to the central office of the association.
+ """
+ excursion = self.excursion
+ context = dict(statement=self.template_context(), excursion=excursion, settings=settings)
+ pdf_filename = f"{excursion.code}_{excursion.name}_Zuschussbeleg" if excursion else f"Abrechnungsbeleg"
+ attachments = [bill.proof.path for bill in self.bills_covered if bill.proof]
+ filename = render_tex_with_attachments(pdf_filename, 'finance/statement_summary.tex',
+ context, attachments, save_only=True)
+ send_mail(_('Statement summary for %(title)s') % { 'title': self.title },
+ settings.SEND_STATEMENT_SUMMARY.format(statement=self.title),
+ sender=settings.DEFAULT_SENDING_MAIL,
+ recipients=[settings.SEKTION_FINANCE_MAIL],
+ cc=cc,
+ attachments=[media_path(filename)])
+
class StatementUnSubmittedManager(models.Manager):
def get_queryset(self):
diff --git a/jdav_web/finance/templates/admin/confirmed_statement.html b/jdav_web/finance/templates/admin/confirmed_statement.html
index 3d35418..23e0c2c 100644
--- a/jdav_web/finance/templates/admin/confirmed_statement.html
+++ b/jdav_web/finance/templates/admin/confirmed_statement.html
@@ -110,6 +110,7 @@ links.forEach(link => {
{% blocktrans %}I did execute the listed transactions.{% endblocktrans %}
-
+
+
{% endblock %}
diff --git a/jdav_web/jdav_web/settings/components/texts.py b/jdav_web/jdav_web/settings/components/texts.py
index e70e3c5..43bc197 100644
--- a/jdav_web/jdav_web/settings/components/texts.py
+++ b/jdav_web/jdav_web/settings/components/texts.py
@@ -273,3 +273,11 @@ Im Anhang findet ihr die Kriseninterventionsliste.
Viele Grüße
Euer KOMPASS""")
+
+SEND_STATEMENT_SUMMARY = get_text('send_statement_summary', default="""Hallo zusammen,
+
+anbei findet ihr die Abrechnung inklusive Belege für {statement}. Die Überweisungen
+wurden wie beschrieben ausgeführt.
+
+Viele Grüße
+Euer KOMPASS""")
diff --git a/jdav_web/jdav_web/settings/local.py b/jdav_web/jdav_web/settings/local.py
index 34dbe5c..71e260c 100644
--- a/jdav_web/jdav_web/settings/local.py
+++ b/jdav_web/jdav_web/settings/local.py
@@ -9,6 +9,7 @@ SEKTION_CONTACT_MAIL = get_var('section', 'contact_mail', default='info@example.
SEKTION_BOARD_MAIL = get_var('section', 'board_mail', default=SEKTION_CONTACT_MAIL)
SEKTION_CRISIS_INTERVENTION_MAIL = get_var('section', 'crisis_intervention_mail',
default=SEKTION_BOARD_MAIL)
+SEKTION_FINANCE_MAIL = get_var('section', 'finance_mail', default=SEKTION_CONTACT_MAIL)
SEKTION_IBAN = get_var('section', 'iban', default='Foo 123')
SEKTION_ACCOUNT_HOLDER = get_var('section', 'account_holder',
default='Foo')