Skip to content
Snippets Groups Projects
Verified Commit 52883be8 authored by Jonathan Weth's avatar Jonathan Weth :keyboard:
Browse files

Send emails to notify about data problems

parent 7e9c9b66
No related branches found
No related tags found
1 merge request!92Resolve "Add task for checking plausibility of data"
...@@ -2,12 +2,14 @@ import logging ...@@ -2,12 +2,14 @@ import logging
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.db.models import F from django.db.models import F
from django.db.models.aggregates import Count
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
import reversion import reversion
from calendarweek import CalendarWeek from calendarweek import CalendarWeek
from templated_email import send_templated_mail
from aleksis.core.util.core_helpers import celery_optional from aleksis.core.util.core_helpers import celery_optional, get_site_preferences
class SolveOption: class SolveOption:
...@@ -97,3 +99,37 @@ def check_data(): ...@@ -97,3 +99,37 @@ def check_data():
for check in DATA_CHECKS: for check in DATA_CHECKS:
logging.info(f"Run check: {check.verbose_name}") logging.info(f"Run check: {check.verbose_name}")
check.check_data() check.check_data()
if get_site_preferences()["alsijil__data_checks_send_emails"]:
send_emails_for_data_checks()
def send_emails_for_data_checks():
"""Notify one or more recipients about new problems with data.
Recipients can be set in dynamic preferences.
"""
from .models import DataCheckResult # noqa
results = DataCheckResult.objects.filter(solved=False, sent=False)
if results.exists():
results_by_check = results.values("check").annotate(count=Count("check"))
results_with_checks = []
for result in results_by_check:
results_with_checks.append(
(DATA_CHECKS_BY_NAME[result["check"]], result["count"])
)
send_templated_mail(
template_name="data_checks",
from_email=get_site_preferences()["mail__address"],
recipient_list=[
p.email
for p in get_site_preferences()["alsijil__data_checks_recipients"]
],
context={"results": results_with_checks},
)
results.update(sent=True)
...@@ -239,6 +239,7 @@ class DataCheckResult(ExtensibleModel): ...@@ -239,6 +239,7 @@ class DataCheckResult(ExtensibleModel):
related_object = GenericForeignKey("content_type", "object_id") related_object = GenericForeignKey("content_type", "object_id")
solved = models.BooleanField(default=False, verbose_name=_("Issue solved")) solved = models.BooleanField(default=False, verbose_name=_("Issue solved"))
sent = models.BooleanField(default=False, verbose_name=_("Notification sent"))
@property @property
def related_check(self) -> DataCheck: def related_check(self) -> DataCheck:
......
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from dynamic_preferences.preferences import Section from dynamic_preferences.preferences import Section
from dynamic_preferences.types import BooleanPreference from dynamic_preferences.types import BooleanPreference, ModelMultipleChoicePreference
from aleksis.core.models import Person
from aleksis.core.registries import site_preferences_registry from aleksis.core.registries import site_preferences_registry
alsijil = Section("alsijil", verbose_name=_("Class register")) alsijil = Section("alsijil", verbose_name=_("Class register"))
...@@ -40,3 +41,24 @@ class AllowOpenPeriodsOnSameDay(BooleanPreference): ...@@ -40,3 +41,24 @@ class AllowOpenPeriodsOnSameDay(BooleanPreference):
help_text = _( help_text = _(
"Lessons in the past are not affected by this setting, you can open them whenever you want." "Lessons in the past are not affected by this setting, you can open them whenever you want."
) )
@site_preferences_registry.register
class DataChecksSendEmails(BooleanPreference):
"""Enable email sending if data checks detect problems."""
section = alsijil
name = "data_checks_send_emails"
default = False
verbose_name = _("Send emails if data checks detect problems")
@site_preferences_registry.register
class DataChecksEmailsRecipients(ModelMultipleChoicePreference):
"""Email recipients for data check problem emails."""
section = alsijil
name = "data_checks_recipients"
default = []
model = Person
verbose_name = _("Email recipients for data checks problem emails")
body {
line-height: 1.5;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
font-weight: normal;
color: rgba(0, 0, 0, 0.87);
}
.count {
text-align: right;
font-family: monospace;
font-size: 14pt;
}
td, th {
padding: 10px;
}
{% load i18n %}
{% block subject %}
{% trans "The system detected some new problems with your data." %}
{% endblock %}
{% block plain %}
{% trans "Hello," %}
{% blocktrans %}
the system detected some new problems with your data in the digital class register.
Please take some time to inspect them and solve the issues or mark them as ignored.
{% endblocktrans %}
{% for result in results %}
{{ result.0.problem_name }}: {{ result.1 }}
{% endfor %}
{% endblock %}
{% block html %}
<style>
{% include "templated_email/data_checks.css" %}
</style>
<p>{% trans "Hello," %}</p>
<p>
{% blocktrans %}
the system detected some new problems with your data in the digital class register.
Please take some time to inspect them and solve the issues or mark them as ignored.
{% endblocktrans %}
</p>
<table>
<tr>
<th>{% trans "Problem description" %}</th>
<th>{% trans "Count of objects with new problems" %}</th>
</tr>
{% for result in results %}
<tr>
<td>{{ result.0.problem_name }}</td>
<td class="count">{{ result.1 }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment