From 36ad17faaab1fe0a89754a1d4e84495714d64724 Mon Sep 17 00:00:00 2001 From: crosspolar <18083323+crosspolar@users.noreply.github.com> Date: Tue, 9 Jun 2026 22:05:42 +0200 Subject: [PATCH 1/3] init --- .../log/templates/log/log_entry_list_tag.html | 7 +++ .../log/logentry_confirm_delete.html | 55 +++++++++++++++++++ tapir/log/urls.py | 5 ++ tapir/log/views.py | 39 ++++++++++++- 4 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 tapir/log/templates/log/logentry_confirm_delete.html diff --git a/tapir/log/templates/log/log_entry_list_tag.html b/tapir/log/templates/log/log_entry_list_tag.html index 9a65ac56d..edd988e83 100644 --- a/tapir/log/templates/log/log_entry_list_tag.html +++ b/tapir/log/templates/log/log_entry_list_tag.html @@ -12,6 +12,13 @@
manage_search {% translate 'See all log entries' %} + {% if perms.accounts.manage %} + + delete_sweep + {% translate 'Delete' %} + + {% endif %}
diff --git a/tapir/log/templates/log/logentry_confirm_delete.html b/tapir/log/templates/log/logentry_confirm_delete.html new file mode 100644 index 000000000..9f083ab3d --- /dev/null +++ b/tapir/log/templates/log/logentry_confirm_delete.html @@ -0,0 +1,55 @@ +{% extends "core/base.html" %} +{% load django_bootstrap5 %} +{% load i18n %} +{% load coop %} +{% load static %} +{% load core %} +{% block head %} + {{ block.super }} + + + {{ filter.form.media }} +{% endblock head %} +{% block content %} +
+
+
+
+
+

+ warning + {% translate "Delete all log entries?" %} +

+
+
+

+ {% blocktranslate with name=share_owner.get_display_name|default:share_owner count=log_count %} + You are about to permanently delete {{ count }} log entries for {{ name }}. + {% endblocktranslate %} +

+ +
+ +
+
+
+
+{% endblock body %} diff --git a/tapir/log/urls.py b/tapir/log/urls.py index bbee4a743..f6eedfb96 100644 --- a/tapir/log/urls.py +++ b/tapir/log/urls.py @@ -19,4 +19,9 @@ views.LogTableView.as_view(), name="log_overview", ), + path( + "delete//", + views.DeleteLogsView.as_view(), + name="delete_logs", + ), ] diff --git a/tapir/log/views.py b/tapir/log/views.py index 1b0dcb83e..5ad9d9afa 100644 --- a/tapir/log/views.py +++ b/tapir/log/views.py @@ -3,12 +3,13 @@ import django_filters import django_tables2 from django.contrib.auth.decorators import login_required, permission_required -from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin from django.contrib.contenttypes.models import ContentType from django.db.models import Q, QuerySet from django.http import HttpResponse, HttpResponseBadRequest -from django.shortcuts import get_object_or_404 +from django.shortcuts import get_object_or_404, redirect, render from django.utils.translation import gettext_lazy as _ +from django.views import View from django.views.decorators.http import require_GET, require_POST from django_filters import DateRangeFilter from django_filters.views import FilterView @@ -20,7 +21,10 @@ from tapir.log.forms import CreateTextLogEntryForm from tapir.log.models import EmailLogEntry, LogEntry, TextLogEntry from tapir.log.util import freeze_for_log -from tapir.settings import PERMISSION_COOP_MANAGE, PERMISSION_COOP_VIEW +from tapir.settings import ( + PERMISSION_COOP_MANAGE, + PERMISSION_COOP_VIEW, +) from tapir.utils.filters import ShareOwnerModelChoiceFilter, TapirUserModelChoiceFilter from tapir.utils.shortcuts import ( safe_redirect, @@ -182,3 +186,32 @@ def get_queryset(self): if not self.request.user.has_perm(PERMISSION_COOP_VIEW): return queryset.filter(user=self.request.user) return queryset + + +class DeleteLogsView(LoginRequiredMixin, PermissionRequiredMixin, View): + + permission_required = "accounts.manage" + raise_exception = True + template_name = "log/logentry_confirm_delete.html" + + def get(self, request, share_owner_id): + share_owner = get_object_or_404(ShareOwner, pk=share_owner_id) + log_count = LogEntry.objects.filter(share_owner=share_owner).count() + + if log_count == 0: + log_count = LogEntry.objects.filter(user=share_owner.user).count() + + context = { + "share_owner": share_owner, + "log_count": log_count, + } + return render(request, self.template_name, context) + + def post(self, request, share_owner_id): + share_owner = get_object_or_404(ShareOwner, pk=share_owner_id) + + deleted_count, _ = LogEntry.objects.filter(share_owner=share_owner).delete() + if deleted_count == 0: + deleted_count, _ = LogEntry.objects.filter(user=share_owner.user).delete() + + return redirect(share_owner.user.get_absolute_url()) From 5263bfca9b9fc5391d388419f6b0302b12e1f184 Mon Sep 17 00:00:00 2001 From: crosspolar <18083323+crosspolar@users.noreply.github.com> Date: Tue, 9 Jun 2026 22:14:21 +0200 Subject: [PATCH 2/3] init --- .../log/logentry_confirm_delete.html | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/tapir/log/templates/log/logentry_confirm_delete.html b/tapir/log/templates/log/logentry_confirm_delete.html index 9f083ab3d..d53a2e0d9 100644 --- a/tapir/log/templates/log/logentry_confirm_delete.html +++ b/tapir/log/templates/log/logentry_confirm_delete.html @@ -6,50 +6,50 @@ {% load core %} {% block head %} {{ block.super }} - + {{ filter.form.media }} {% endblock head %} {% block content %} -
-
-
-
-
-

- warning - {% translate "Delete all log entries?" %} -

-
-
-

- {% blocktranslate with name=share_owner.get_display_name|default:share_owner count=log_count %} - You are about to permanently delete {{ count }} log entries for {{ name }}. - {% endblocktranslate %} -

- -
- +
+
+
+
+
+ warning + {% translate "Delete all log entries?" %} +
+
    +
  • +

    + {% blocktranslate with name=share_owner.get_display_name|default:share_owner count=log_count %} + You are about to permanently delete {{ count }} log entries for {{ name }}. + {% endblocktranslate %} +

    + +
  • +
  • + {% translate "Cancel" %} +
    + {% csrf_token %} + +
    +
  • +
-{% endblock body %} +{% endblock content %} From 9b66b73c70e2cd05f0f9b74d8f11ec5cdaf867d4 Mon Sep 17 00:00:00 2001 From: crosspolar <18083323+crosspolar@users.noreply.github.com> Date: Wed, 10 Jun 2026 07:20:49 +0200 Subject: [PATCH 3/3] fix: for general accounts without share-owner --- .../log/templates/log/log_entry_list_tag.html | 2 +- tapir/log/templatetags/tapir_log.py | 2 + .../locale/de/LC_MESSAGES/django.po | 58 +++++++++++++++---- 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/tapir/log/templates/log/log_entry_list_tag.html b/tapir/log/templates/log/log_entry_list_tag.html index edd988e83..d239a2930 100644 --- a/tapir/log/templates/log/log_entry_list_tag.html +++ b/tapir/log/templates/log/log_entry_list_tag.html @@ -14,7 +14,7 @@
+ href="{% url 'log:delete_logs' share_owner_id %}"> delete_sweep {% translate 'Delete' %} diff --git a/tapir/log/templatetags/tapir_log.py b/tapir/log/templatetags/tapir_log.py index b38dcb578..5d484628d 100644 --- a/tapir/log/templatetags/tapir_log.py +++ b/tapir/log/templatetags/tapir_log.py @@ -42,6 +42,8 @@ def log_entry_list(context, **kwargs): share_owner_id = tapir_user.share_owner.id elif share_owner: share_owner_id = share_owner.id + else: + share_owner_id = tapir_user.id context["share_owner_id"] = share_owner_id context["create_text_log_entry_action_url"] = reverse( diff --git a/tapir/translations/locale/de/LC_MESSAGES/django.po b/tapir/translations/locale/de/LC_MESSAGES/django.po index ce1f84ca4..bc18bf71b 100644 --- a/tapir/translations/locale/de/LC_MESSAGES/django.po +++ b/tapir/translations/locale/de/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-06-09 08:36+0200\n" +"POT-Creation-Date: 2026-06-10 07:18+0200\n" "PO-Revision-Date: 2025-07-07 13:06+0000\n" "Last-Translator: Weblate Admin \n" "Language-Team: German \n" @@ -309,8 +309,8 @@ msgstr "Du kannst nur deinen eigenen Strichcode sehen, es sei denn du hast Admin #: accounts/templates/accounts/user_detail.html:20 coop/models.py:724 #: coop/templates/coop/draftuser_detail.html:86 -#: coop/templates/coop/shareowner_detail.html:10 log/views.py:94 -#: log/views.py:152 shifts/templates/shifts/shift_detail_printable.html:50 +#: coop/templates/coop/shareowner_detail.html:10 log/views.py:98 +#: log/views.py:156 shifts/templates/shifts/shift_detail_printable.html:50 msgid "Member" msgstr "Mitglied" @@ -960,6 +960,7 @@ msgstr "Löschen bestätigen" #: coop/templates/coop/confirm_delete_share_ownership.html:24 #: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:133 #: financingcampaign/templates/financingcampaign/confirm_delete.html:24 +#: log/templates/log/log_entry_list_tag.html:19 #: shifts/templates/shifts/shift_confirm_delete.html:30 msgid "Delete" msgstr "Löschen" @@ -2089,6 +2090,7 @@ msgid "Submit" msgstr "Abschicken" #: coop/templates/coop/extra_share_request.html:92 +#: log/templates/log/logentry_confirm_delete.html:44 #: shifts/templates/shifts/user_shifts_overview_tag.html:177 msgid "Cancel" msgstr "Abmelden" @@ -2946,7 +2948,7 @@ msgid "The list of all datapoints" msgstr "" #: financingcampaign/templates/financingcampaign/general.html:111 -#: log/templates/log/log_entry_list_tag.html:23 +#: log/templates/log/log_entry_list_tag.html:30 #: shifts/templates/shifts/user_shift_account_log.html:26 #: statistics/templates/statistics/tags/credit_account_card.html:17 #: statistics/templates/statistics/tags/purchase_statistics_card.html:18 @@ -3013,29 +3015,61 @@ msgstr "Letzte 5 Log-Einträge" msgid "See all log entries" msgstr "Alle Log-Einträge einsehen" -#: log/templates/log/log_entry_list_tag.html:20 +#: log/templates/log/log_entry_list_tag.html:27 msgid "List of log entries for this member" msgstr "Liste der Protokoll-Einträge für dieses Mitglied" -#: log/templates/log/log_entry_list_tag.html:24 log/views.py:97 -#: log/views.py:151 +#: log/templates/log/log_entry_list_tag.html:31 log/views.py:101 +#: log/views.py:155 msgid "Actor" msgstr "Sender*in" -#: log/templates/log/log_entry_list_tag.html:25 log/views.py:90 +#: log/templates/log/log_entry_list_tag.html:32 log/views.py:94 msgid "Message" msgstr "Nachricht" -#: log/templates/log/log_entry_list_tag.html:57 -#: log/templates/log/log_entry_list_tag.html:58 +#: log/templates/log/log_entry_list_tag.html:64 +#: log/templates/log/log_entry_list_tag.html:65 msgid "Notes about this user" msgstr "Notizen über diese*n Benutzer*in" -#: log/templates/log/log_entry_list_tag.html:63 +#: log/templates/log/log_entry_list_tag.html:70 msgid "Add Note" msgstr "Notiz hinzufügen" -#: log/views.py:153 +#: log/templates/log/logentry_confirm_delete.html:24 +#, fuzzy +#| msgid "See all log entries" +msgid "Delete all log entries?" +msgstr "Alle Log-Einträge einsehen" + +#: log/templates/log/logentry_confirm_delete.html:32 +#, python-format +msgid "" +"\n" +" You are about to permanently delete %(count)s log entries for %(name)s.\n" +" " +msgstr "" + +#: log/templates/log/logentry_confirm_delete.html:37 +msgid "Warning:" +msgstr "" + +#: log/templates/log/logentry_confirm_delete.html:38 +msgid "This action cannot be undone!" +msgstr "" + +#: log/templates/log/logentry_confirm_delete.html:39 +msgid "This action may skew statistics based on the logs!" +msgstr "" + +#: log/templates/log/logentry_confirm_delete.html:49 +#, fuzzy +#| msgid "See all log entries" +msgid "Delete all logs" +msgstr "Alle Log-Einträge einsehen" + +#: log/views.py:157 msgid "Log Type" msgstr ""