From 9a29ded81d709b865bd34c7358a8e0b26427ab65 Mon Sep 17 00:00:00 2001 From: crosspolar <18083323+crosspolar@users.noreply.github.com> Date: Fri, 17 Apr 2026 19:40:21 +0200 Subject: [PATCH 01/14] init --- tapir/shifts/forms.py | 13 ++++++ .../migrations/0075_shifttemplate_end_date.py | 22 +++++++++ tapir/shifts/models.py | 14 ++++-- tapir/shifts/services/shift_generator.py | 9 +++- .../shifts/shift_template_detail.html | 5 ++ .../shifts/shift_template_set_end_date.html | 29 ++++++++++++ tapir/shifts/urls.py | 6 +++ tapir/shifts/views/views.py | 46 +++++++++++++++++++ 8 files changed, 138 insertions(+), 6 deletions(-) create mode 100644 tapir/shifts/migrations/0075_shifttemplate_end_date.py create mode 100644 tapir/shifts/templates/shifts/shift_template_set_end_date.html diff --git a/tapir/shifts/forms.py b/tapir/shifts/forms.py index 8fc2ee0bb..0f16ea153 100644 --- a/tapir/shifts/forms.py +++ b/tapir/shifts/forms.py @@ -459,6 +459,19 @@ def clean(self): return result +class ShiftTemplateEndDateForm(forms.ModelForm): + cancellation_reason = forms.CharField(label=_("Cancellation Reason"), required=True) + + class Meta: + model = ShiftTemplate + fields = ["end_date"] + widgets = {"end_date": DateInputTapir()} + + def __init__(self, shift_template=None, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields["end_date"].required = True + + class CreateShiftAccountEntryForm(forms.ModelForm): class Meta: model = ShiftAccountEntry diff --git a/tapir/shifts/migrations/0075_shifttemplate_end_date.py b/tapir/shifts/migrations/0075_shifttemplate_end_date.py new file mode 100644 index 000000000..f0bee3db1 --- /dev/null +++ b/tapir/shifts/migrations/0075_shifttemplate_end_date.py @@ -0,0 +1,22 @@ +# Generated by Django 5.2.13 on 2026-04-17 16:42 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("shifts", "0074_alter_shift_num_required_attendances"), + ] + + operations = [ + migrations.AddField( + model_name="shifttemplate", + name="end_date", + field=models.DateField( + blank=True, + help_text="All shifts after this date will be cancelled.", + null=True, + ), + ), + ] diff --git a/tapir/shifts/models.py b/tapir/shifts/models.py index b639b9778..315e9ebad 100644 --- a/tapir/shifts/models.py +++ b/tapir/shifts/models.py @@ -178,6 +178,11 @@ class ShiftTemplate(models.Model): "This determines from which date shifts should be generated from this ABCD shift." ), ) + end_date = models.DateField( + blank=True, + null=True, + help_text=_("All shifts after this date will be cancelled."), + ) flexible_time = models.BooleanField( verbose_name=_("Flexible time"), help_text=_( @@ -292,10 +297,11 @@ def update_future_generated_shifts_to_fit_this(self): shift.update_to_fit_template() def clean(self): - if self.start_time >= self.end_time: - raise ValidationError( - f"The shift must end after it starts. Given start time: {self.start_time}. Given end time: {self.end_time}" - ) + if self.start_time and self.end_time: + if self.start_time >= self.end_time: + raise ValidationError( + f"The shift must end after it starts. Given start time: {self.start_time}. Given end time: {self.end_time}" + ) class RequiredCapabilitiesMixin: diff --git a/tapir/shifts/services/shift_generator.py b/tapir/shifts/services/shift_generator.py index ea4c828c6..c8b4e3902 100644 --- a/tapir/shifts/services/shift_generator.py +++ b/tapir/shifts/services/shift_generator.py @@ -56,8 +56,13 @@ def create_shifts_for_group( start_date_in_the_past_or_null = Q(start_date__lte=at_date) | Q( start_date__isnull=True ) - shift_templates = ShiftTemplate.objects.filter(group=group).filter( - start_date_in_the_past_or_null + end_date_in_the_future_or_null = Q(end_date__gte=at_date) | Q( + end_date__isnull=True + ) + shift_templates = ( + ShiftTemplate.objects.filter(group=group) + .filter(start_date_in_the_past_or_null) + .filter(end_date_in_the_future_or_null) ) if filter_shift_template_ids is not None: diff --git a/tapir/shifts/templates/shifts/shift_template_detail.html b/tapir/shifts/templates/shifts/shift_template_detail.html index b1ee5d22d..132770826 100644 --- a/tapir/shifts/templates/shifts/shift_template_detail.html +++ b/tapir/shifts/templates/shifts/shift_template_detail.html @@ -28,6 +28,11 @@
edit {% translate "Edit" %} + + event_busy + {% translate 'Set end date' %} + {% endif %}
diff --git a/tapir/shifts/templates/shifts/shift_template_set_end_date.html b/tapir/shifts/templates/shifts/shift_template_set_end_date.html new file mode 100644 index 000000000..938bb683b --- /dev/null +++ b/tapir/shifts/templates/shifts/shift_template_set_end_date.html @@ -0,0 +1,29 @@ +{% extends "shifts/base.html" %} +{% load django_bootstrap5 %} +{% load static %} +{% load i18n %} +{% load core %} +{% block title %} + {% translate 'Set end date for' %}: {{ shift_template.get_display_name }} +{% endblock title %} +{% block content %} +
+
{% translate 'Set end date for' %}: {{ shift_template.get_display_name }}
+
+
+ {% csrf_token %} + {% bootstrap_form form %} + + + {% translate 'Cancel' %} +
+
+
+{% endblock content %} diff --git a/tapir/shifts/urls.py b/tapir/shifts/urls.py index 7ec077acd..9f6281e50 100644 --- a/tapir/shifts/urls.py +++ b/tapir/shifts/urls.py @@ -1,6 +1,7 @@ from django.urls import path from tapir.shifts import views +from tapir.shifts.views import ShiftTemplateEndDateView app_name = "shifts" urlpatterns = [ @@ -240,4 +241,9 @@ views.RecurringShiftwatchListView.as_view(), name="shiftwatch_overview", ), + path( + "shift_template//set_end_date/", + ShiftTemplateEndDateView.as_view(), + name="shift_template_set_end_date", + ), ] diff --git a/tapir/shifts/views/views.py b/tapir/shifts/views/views.py index 4897ebec6..8b61ffcc0 100644 --- a/tapir/shifts/views/views.py +++ b/tapir/shifts/views/views.py @@ -16,10 +16,12 @@ CreateView, UpdateView, RedirectView, + FormView, ) from django.views.generic import DetailView, TemplateView from django_tables2 import SingleTableView from django_tables2.export import ExportMixin +from redis.commands.search import result from tapir.accounts.models import TapirUser from tapir.core.config import ( @@ -40,6 +42,7 @@ CreateShiftAccountEntryForm, ShiftWatchForm, RecurringShiftWatchForm, + ShiftTemplateEndDateForm, ) from tapir.shifts.models import ( @@ -56,6 +59,7 @@ ShiftUserData, ShiftAccountEntry, ) +from tapir.shifts.services.shift_cancellation_service import ShiftCancellationService from tapir.shifts.services.shift_watch_creation_service import ShiftWatchCreator from tapir.shifts.templatetags.shifts import shift_name_as_class from tapir.utils.user_utils import UserUtils @@ -289,6 +293,48 @@ def get_queryset(self): ) +class ShiftTemplateEndDateView( + LoginRequiredMixin, + PermissionRequiredMixin, + # TapirFormMixin, + generic.UpdateView, +): + permission_required = PERMISSION_SHIFTS_MANAGE + form_class = ShiftTemplateEndDateForm + template_name = "shifts/shift_template_set_end_date.html" + model = ShiftTemplate + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["shift_template"] = self.object + return context + + def get_success_url(self): + return reverse("shifts:shift_template_detail", kwargs={"pk": self.object.pk}) + + def form_valid(self, form): + with transaction.atomic(): + response = super().form_valid(form) + end_date = form.cleaned_data["end_date"] + cancellation_reason = form.cleaned_data["cancellation_reason"] + shifts_to_cancel = Shift.objects.filter( + shift_template=self.object, + start_time__date__gt=end_date, + deleted=False, + cancelled=False, + ) + for shift in shifts_to_cancel: + shift.cancelled_reason = cancellation_reason + ShiftCancellationService.cancel(shift) + + messages.success( + self.request, + _("Shift template was successfully cancelled"), + ) + + return response + + class ShiftUserDataTable(django_tables2.Table): class Meta: model = ShiftUserData From 1d7136f3b50c6d44eb43207d1f951d498f4d9592 Mon Sep 17 00:00:00 2001 From: crosspolar <18083323+crosspolar@users.noreply.github.com> Date: Sat, 18 Apr 2026 07:39:34 +0200 Subject: [PATCH 02/14] translation --- .../locale/de/LC_MESSAGES/django.po | 192 +++++++++++------- 1 file changed, 114 insertions(+), 78 deletions(-) diff --git a/tapir/translations/locale/de/LC_MESSAGES/django.po b/tapir/translations/locale/de/LC_MESSAGES/django.po index cd6b9f553..e5998bd4e 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-03-15 12:03+0100\n" +"POT-Creation-Date: 2026-04-18 07:38+0200\n" "PO-Revision-Date: 2025-07-07 13:06+0000\n" "Last-Translator: Weblate Admin \n" "Language-Team: German \n" @@ -343,7 +343,7 @@ msgstr "Benutzername bearbeiten" #: core/templates/core/featureflag_list.html:30 #: shifts/templates/shifts/shift_detail.html:61 #: shifts/templates/shifts/shift_template_detail.html:29 -#: shifts/templates/shifts/shift_template_detail.html:117 +#: shifts/templates/shifts/shift_template_detail.html:122 #: shifts/templates/shifts/user_shifts_overview_tag.html:14 msgid "Edit" msgstr "Bearbeiten" @@ -1084,7 +1084,7 @@ msgstr "Bewerber*in erzeugen" #: shifts/templates/shifts/register_user_to_shift_slot.html:27 #: shifts/templates/shifts/register_user_to_shift_slot_template.html:26 #: shifts/templates/shifts/shift_detail.html:243 -#: shifts/templates/shifts/shift_template_detail.html:88 +#: shifts/templates/shifts/shift_template_detail.html:93 msgid "Register" msgstr "Anmelden" @@ -2149,7 +2149,7 @@ msgstr "" " " #: coop/templates/coop/membershipresignation_detail.html:61 -#: shifts/models.py:536 +#: shifts/models.py:542 msgid "Cancellation reason" msgstr "Grund der Kündigung" @@ -2382,7 +2382,7 @@ msgid "" msgstr "" #: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:56 -#: shifts/models.py:934 shifts/templates/shifts/shift_day_printable.html:214 +#: shifts/models.py:940 shifts/templates/shifts/shift_day_printable.html:214 #: shifts/templates/shifts/shift_day_printable.html:276 #: shifts/templates/shifts/shift_detail.html:298 #: shifts/templates/shifts/shift_detail_printable.html:51 @@ -2390,7 +2390,7 @@ msgid "Attended" msgstr "Teilgenommen" #: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:58 -#: shifts/models.py:933 +#: shifts/models.py:939 msgid "Pending" msgstr "Ausstehend" @@ -2563,7 +2563,7 @@ msgstr "Hat Qualifikation" msgid "Does not have qualification" msgstr "Hat die Qualifikation nicht" -#: coop/views/shareowner.py:647 shifts/forms.py:777 +#: coop/views/shareowner.py:647 shifts/forms.py:790 msgid "ABCD Week" msgstr "ABCD-Woche" @@ -2692,8 +2692,8 @@ msgstr "" msgid "List of all emails" msgstr "Liste alle E-Mails" -#: core/templates/core/email_list.html:39 shifts/models.py:503 -#: shifts/models.py:1072 shifts/templates/shifts/user_shift_account_log.html:29 +#: core/templates/core/email_list.html:39 shifts/models.py:509 +#: shifts/models.py:1078 shifts/templates/shifts/user_shift_account_log.html:29 msgid "Description" msgstr "Beschreibung" @@ -3038,78 +3038,78 @@ msgstr "Das ausgewählte Mitglied muss ein investierendes Mitglied sein." msgid "This member is registered to at least one ABCD shift. Please confirm the change of attendance mode with the checkbox below." msgstr "" -#: shifts/forms.py:497 +#: shifts/forms.py:463 shifts/forms.py:621 +msgid "Cancellation Reason" +msgstr "Grund der Absage" + +#: shifts/forms.py:510 msgid "I have read the warning about the cancelled attendances and confirm that the exemption should be created" msgstr "Ich habe die Warnung über die abgesagte Schicht-Anwesenheit gelesen und bestätige, dass die Befreiung erzeugt werden soll" -#: shifts/forms.py:504 +#: shifts/forms.py:517 msgid "I have read the warning about the cancelled ABCD attendances and confirm that the exemption should be created" msgstr "Ich habe die Warnung über die abgebrochene ABCD-Teilnahme gelesen und bestätige, dass die Befreiung erzeugt werden soll" -#: shifts/forms.py:562 +#: shifts/forms.py:575 #, python-format msgid "The user will be unregistered from the following ABCD shifts because the exemption is longer than %(number_of_cycles)s cycles: %(attendances_display)s " msgstr "Das Mitglied wird von den folgenden ABCD-Schichten abgemeldet, weil die Befreiung länger als %(number_of_cycles)s Schichtzyklen ist: %(attendances_display)s " -#: shifts/forms.py:583 +#: shifts/forms.py:596 msgid "This shift has been deleted. It is not possible to cancel it." msgstr "Diese Schicht wurde bereits gelöscht. Es ist nicht möglich diese abzusagen." -#: shifts/forms.py:594 shifts/templates/shifts/shift_detail.html:8 +#: shifts/forms.py:607 shifts/templates/shifts/shift_detail.html:8 #: shifts/templates/shifts/shift_detail.html:30 msgid "Shift" msgstr "Schicht" -#: shifts/forms.py:595 +#: shifts/forms.py:608 msgid "already cancelled" msgstr "bereits bgesagt" -#: shifts/forms.py:608 -msgid "Cancellation Reason" -msgstr "Grund der Absage" - -#: shifts/forms.py:609 +#: shifts/forms.py:622 msgid "This reason will be applied to all cancelled shifts." msgstr "" -#: shifts/forms.py:637 +#: shifts/forms.py:650 msgid "I understand that updating this ABCD shift will update all the corresponding future shifts" msgstr "" -#: shifts/forms.py:656 +#: shifts/forms.py:669 msgid "ABCD-Week" msgstr "ABCD-Woche" -#: shifts/forms.py:660 +#: shifts/forms.py:673 msgid "Weekdays" msgstr "Wochentage" -#: shifts/forms.py:685 +#: shifts/forms.py:698 msgid "I understand that adding or editing a slot to this ABCD shift will affect all the corresponding future shifts" msgstr "" -#: shifts/forms.py:694 +#: shifts/forms.py:707 msgid "I understand that this will delete the shift exemption and create a membership pause" msgstr "" -#: shifts/forms.py:726 shifts/forms.py:782 shifts/views/views.py:379 -#: shifts/views/views.py:380 +#: shifts/forms.py:739 shifts/forms.py:795 shifts/views/views.py:425 +#: shifts/views/views.py:426 msgid "Shift changes you would like to be informed about" msgstr "Schicht-Änderungen, bei denen du informiert werden möchtest" -#: shifts/forms.py:771 shifts/templates/shifts/shift_template_detail.html:7 +#: shifts/forms.py:784 shifts/templates/shifts/shift_template_detail.html:7 #: shifts/templates/shifts/shift_template_detail.html:15 #: shifts/templates/shifts/user_shifts_overview_tag.html:31 #: shifts/templates/shifts/user_shifts_overview_tag.html:43 msgid "ABCD Shift" msgstr "ABCD-Schicht" -#: shifts/forms.py:788 +#: shifts/forms.py:801 #, python-format msgid "If weekdays or %(shift_template_group)s are selected, %(shift_templates)s may not be selected, and vice versa." msgstr "" -#: shifts/forms.py:792 +#: shifts/forms.py:805 #, python-format msgid "At least one of the fields (%(shift_templates)s, weekdays, or %(shift_template_group)s) must be selected." msgstr "" @@ -3174,7 +3174,7 @@ msgstr "Mir ist klar, dass ich bei dieser Schicht möglicherweise schwere Gewich msgid "I understand that I may need to work high, for example up a ladder. I do not suffer from fear of heights." msgstr "Mir ist klar, dass ich möglicherweise in großer Höhe arbeiten muss, zum Beispiel auf einer Leiter. Ich leide nicht unter Höhenangst." -#: shifts/models.py:167 shifts/models.py:497 +#: shifts/models.py:167 shifts/models.py:503 msgid "If there are less members registered to a shift than that number, it will be highlighted in the shift calendar. The number of required attendances can't be higher than the slots in the resp. shift." msgstr "Wenn weniger Mitlieder als diese Nummer zur Schicht registriert sind, wird diese blau angezeigt. Die Anzahl der benltigten Mitglieder kann nicht höher sein als die Anzahl vorhandener Slots." @@ -3182,47 +3182,51 @@ msgstr "Wenn weniger Mitlieder als diese Nummer zur Schicht registriert sind, wi msgid "This determines from which date shifts should be generated from this ABCD shift." msgstr "" -#: shifts/models.py:182 shifts/models.py:511 +#: shifts/models.py:184 +msgid "All shifts after this date will be cancelled." +msgstr "" + +#: shifts/models.py:187 shifts/models.py:517 #: shifts/templates/shifts/shift_block_tag.html:11 msgid "Flexible time" msgstr "Zeit flexibel" -#: shifts/models.py:184 shifts/models.py:513 +#: shifts/models.py:189 shifts/models.py:519 msgid "If enabled, members who register for that shift can choose themselves the time where they come do their shift." msgstr "" -#: shifts/models.py:409 shifts/models.py:825 +#: shifts/models.py:415 shifts/models.py:831 #: shifts/templates/shifts/shift_detail.html:112 -#: shifts/templates/shifts/shift_template_detail.html:46 +#: shifts/templates/shifts/shift_template_detail.html:51 msgid "Chosen time" msgstr "Ausgewählte Uhrzeit" -#: shifts/models.py:411 +#: shifts/models.py:417 msgid "This shift lets you choose at what time you come during the day of the shift. In order to help organising the attendance, please specify when you expect to come.Setting or updating this field will set the time for all individual shifts generated from this ABCD shift.You can update the time of a single shift individually and at any time on the shift page." msgstr "" -#: shifts/models.py:495 +#: shifts/models.py:501 msgid "Number of required attendances" msgstr "Anzahl notwendiger Teilnehmender" -#: shifts/models.py:504 +#: shifts/models.py:510 msgid "Is shown on the shift page below the title" msgstr "" -#: shifts/models.py:524 shifts/models.py:530 +#: shifts/models.py:530 shifts/models.py:536 msgid "If 'flexible time' is enabled, then the time component is ignored" msgstr "" -#: shifts/models.py:827 +#: shifts/models.py:833 msgid "This shift lets you choose at what time you come during the day of the shift. In order to help organising the attendance, please specify when you expect to come." msgstr "Diese Schicht ermöglicht dir auszusuchen, wann du kommen magst. Um die Planung zu erleichtern, gib bitte deine erwartete Ankunftszeit an." -#: shifts/models.py:935 shifts/templates/shifts/shift_detail.html:308 +#: shifts/models.py:941 shifts/templates/shifts/shift_detail.html:308 #: shifts/templates/shifts/shift_detail_printable.html:52 msgid "Missed" msgstr "Nicht erschienen" -#: shifts/models.py:936 shifts/templates/shifts/shift_day_printable.html:216 +#: shifts/models.py:942 shifts/templates/shifts/shift_day_printable.html:216 #: shifts/templates/shifts/shift_day_printable.html:281 #: shifts/templates/shifts/shift_day_printable.html:283 #: shifts/templates/shifts/shift_detail.html:338 @@ -3230,66 +3234,66 @@ msgstr "Nicht erschienen" msgid "Excused" msgstr "Entschuldigt" -#: shifts/models.py:937 shifts/templates/shifts/shift_detail.html:346 +#: shifts/models.py:943 shifts/templates/shifts/shift_detail.html:346 msgid "Cancelled" msgstr "Abgesagt" -#: shifts/models.py:938 shifts/templates/shifts/shift_day_printable.html:264 +#: shifts/models.py:944 shifts/templates/shifts/shift_day_printable.html:264 #: shifts/templates/shifts/shift_detail.html:330 #: shifts/templates/shifts/shift_detail_printable.html:94 #: shifts/templates/shifts/shift_filters.html:83 msgid "Looking for a stand-in" msgstr "Sucht Vertretung" -#: shifts/models.py:971 +#: shifts/models.py:977 msgid "🏠 ABCD" msgstr "🏠 ABCD" -#: shifts/models.py:972 +#: shifts/models.py:978 msgid "✈ Flying" msgstr "✈ Fliegend" -#: shifts/models.py:973 +#: shifts/models.py:979 msgid "❄ Frozen" msgstr "❄ Eingefroren" -#: shifts/models.py:1004 +#: shifts/models.py:1010 msgid "Is frozen" msgstr "Ist eingefroren" -#: shifts/models.py:1178 +#: shifts/models.py:1184 msgid "Cycle start date" msgstr "Anfangsdatum" -#: shifts/models.py:1199 +#: shifts/models.py:1205 msgid "Shift is almost full, only one spot left." msgstr "Die Schicht ist fast voll, es ist nur noch ein Platz übrig." -#: shifts/models.py:1200 +#: shifts/models.py:1206 msgid "Shift is full now." msgstr "Die Schicht ist jetzt voll." -#: shifts/models.py:1201 +#: shifts/models.py:1207 msgid "The Shift is understaffed!" msgstr "Die Schicht ist jetzt unterbesetzt." -#: shifts/models.py:1202 +#: shifts/models.py:1208 msgid "Shift stable: not understaffed, not fully staffed." msgstr "Entwarnung. Die schicht ist nicht länger unterbesetzt, aber es noch Platz übrig" -#: shifts/models.py:1204 +#: shifts/models.py:1210 msgid "One new attendance or more registered, but the shift is neither understaffed nor full or almost full." msgstr "Ein Mitglied oder mehr hat sich registriert, aber die Schicht ist weder unterbesetzt noch (fast) voll" -#: shifts/models.py:1207 +#: shifts/models.py:1213 msgid "One attendance or more un-registered, but the shift is neither understaffed nor full or almost full." msgstr "Ein Mitglied oder mehr hat sich abgemeldet, aber die Schicht ist weder unterbesetzt noch (fast) voll" -#: shifts/models.py:1210 +#: shifts/models.py:1216 msgid "The Shift Coordinator has unregistered" msgstr "Ein Teamleiter hat sich abgemeldet" -#: shifts/models.py:1213 +#: shifts/models.py:1219 msgid "A Shift Coordinator has registered" msgstr "Ein Teamleiter hat sich angemeldet" @@ -4112,7 +4116,7 @@ msgstr "Flexible Arbeitszeit nicht angegeben" #: shifts/templates/shifts/shift_day_printable.html:259 #: shifts/templates/shifts/shift_detail.html:139 #: shifts/templates/shifts/shift_detail_printable.html:90 -#: shifts/templates/shifts/shift_template_detail.html:68 +#: shifts/templates/shifts/shift_template_detail.html:73 msgid "Shift partner: " msgstr "Schicht-Partner: " @@ -4176,12 +4180,12 @@ msgid "Number" msgstr "Nummer" #: shifts/templates/shifts/shift_detail.html:106 -#: shifts/templates/shifts/shift_template_detail.html:42 +#: shifts/templates/shifts/shift_template_detail.html:47 msgid "Details" msgstr "Details" #: shifts/templates/shifts/shift_detail.html:107 -#: shifts/templates/shifts/shift_template_detail.html:44 +#: shifts/templates/shifts/shift_template_detail.html:49 msgid "Registered user" msgstr "Angemeldete*r Nutzer*in" @@ -4194,7 +4198,7 @@ msgid "Do you meet the requirements?" msgstr "Erfüllst du die Voraussetzungen?" #: shifts/templates/shifts/shift_detail.html:115 -#: shifts/templates/shifts/shift_template_detail.html:49 +#: shifts/templates/shifts/shift_template_detail.html:54 msgid "Member-Office actions" msgstr "Mitgliederbüro Aktionen" @@ -4300,7 +4304,7 @@ msgstr "" " " #: shifts/templates/shifts/shift_detail.html:271 -#: shifts/templates/shifts/shift_template_detail.html:99 +#: shifts/templates/shifts/shift_template_detail.html:104 msgid "Not specified" msgstr "" @@ -4429,23 +4433,29 @@ msgstr "" msgid "Duplicate" msgstr "Dopplung" -#: shifts/templates/shifts/shift_template_detail.html:38 +#: shifts/templates/shifts/shift_template_detail.html:34 +#, fuzzy +#| msgid "Pay out end date" +msgid "Set end date" +msgstr "Auszahlungsende" + +#: shifts/templates/shifts/shift_template_detail.html:43 msgid "List of slots for this ABCD shifts" msgstr "Liste des Slots für diese ABCD-Schicht" -#: shifts/templates/shifts/shift_template_detail.html:43 +#: shifts/templates/shifts/shift_template_detail.html:48 msgid "Requirements" msgstr "" -#: shifts/templates/shifts/shift_template_detail.html:77 +#: shifts/templates/shifts/shift_template_detail.html:82 msgid "Unregister" msgstr "Abmelden" -#: shifts/templates/shifts/shift_template_detail.html:126 +#: shifts/templates/shifts/shift_template_detail.html:131 msgid "Future generated Shifts" msgstr "Zukünftige erstellte Schichten" -#: shifts/templates/shifts/shift_template_detail.html:136 +#: shifts/templates/shifts/shift_template_detail.html:141 msgid "Past generated Shifts" msgstr "Vergangene Schichten" @@ -4484,6 +4494,32 @@ msgstr "" msgid "Calendar of ABCD shifts" msgstr "Kalender der ABCD-Schichten" +#: shifts/templates/shifts/shift_template_set_end_date.html:7 +#: shifts/templates/shifts/shift_template_set_end_date.html:11 +#, fuzzy +#| msgid "Pay out end date" +msgid "Set end date for" +msgstr "Auszahlungsende" + +#: shifts/templates/shifts/shift_template_set_end_date.html:17 +msgid "Warning" +msgstr "" + +#: shifts/templates/shifts/shift_template_set_end_date.html:18 +msgid "All shifts generated from this ABCD-shift after the selected date will be cancelled. Registered members will be notified." +msgstr "" + +#: shifts/templates/shifts/shift_template_set_end_date.html:22 +#, fuzzy +#| msgid "Set shift attendance to" +msgid "Set end date and cancel shifts" +msgstr "Ändere den Schichtstatus zu" + +#: shifts/templates/shifts/shift_template_set_end_date.html:25 +#: shifts/templates/shifts/user_shifts_overview_tag.html:177 +msgid "Cancel" +msgstr "Abmelden" + #: shifts/templates/shifts/shiftexemption_list.html:38 msgid "Create shift exemption" msgstr "Schicht-Befreiung erzeugen" @@ -4515,7 +4551,7 @@ msgid "Recurring Shift Watches" msgstr "Wiederholende Schichtbeobachtungen" #: shifts/templates/shifts/shiftwatch_overview.html:25 -#: shifts/views/views.py:424 +#: shifts/views/views.py:470 msgid "Create a rule for recurring Shift Watches" msgstr "Erstelle eine Regel für sich wiederholende Schichtbeobachtungen" @@ -4762,10 +4798,6 @@ msgstr "Solidaritäts-Schicht spenden" msgid "One of your banked shifts will be donated as a solidarity shift. Do you want to continue?" msgstr "Eine deiner gearbeiteten Schichten wird als Solidaritäts-Schicht gespendet. Möchtest du fortfahren?" -#: shifts/templates/shifts/user_shifts_overview_tag.html:177 -msgid "Cancel" -msgstr "Abmelden" - #: shifts/templates/shifts/user_shifts_overview_tag.html:180 msgid "Confirm" msgstr "" @@ -4853,7 +4885,7 @@ msgid "No watched shifts" msgstr "Keine beobachteten Schichten" #: shifts/templatetags/shifts.py:70 shifts/templatetags/shifts.py:175 -#: shifts/views/views.py:152 +#: shifts/views/views.py:156 msgid "General" msgstr "Allgemein" @@ -4952,27 +4984,31 @@ msgstr "Es konnte keine vollendete Schicht gefunden werden, die als Solidarität msgid "Solidarity Shift given. Account Balance debited with -1." msgstr "Die Solidaritätsschicht wurde vergeben. Von deinem Kontostand wird nun eine Schicht abgezogen." -#: shifts/views/views.py:132 shifts/views/views.py:137 +#: shifts/views/views.py:136 shifts/views/views.py:141 #, python-format msgid "Edit user shift data: %(name)s" msgstr "Bearbeite Nutzer*in-Schichtdaten: %(name)s" -#: shifts/views/views.py:205 +#: shifts/views/views.py:209 #, python-format msgid "Shift account: %(name)s" msgstr "Schichtkonto-Protokoll für: %(name)s" -#: shifts/views/views.py:211 +#: shifts/views/views.py:215 #, fuzzy, python-format #| msgid "Create manual shift account entry for: %(link)s" msgid "Create manual shift account entry for: %(link)s" msgstr "Erzeuge Schicht-Kontoeintrag für: %(link)s" -#: shifts/views/views.py:362 +#: shifts/views/views.py:332 +msgid "Shift template was successfully cancelled" +msgstr "" + +#: shifts/views/views.py:408 msgid "Frozen statuses updated." msgstr "" -#: shifts/views/views.py:427 +#: shifts/views/views.py:473 #, python-format msgid "Please select either %(shift_template_group)s and/or weekdays, or alternatively %(shift_templates)s." msgstr "" From 122758edcf1dfcb2428e0dda4f3cdd45f7bc1b28 Mon Sep 17 00:00:00 2001 From: crosspolar <18083323+crosspolar@users.noreply.github.com> Date: Sat, 18 Apr 2026 08:56:54 +0200 Subject: [PATCH 03/14] init TestShiftTemplateEndView --- .../tests/test_shifttemplateenddateview.py | 88 +++++++++++++++++++ tapir/shifts/views/views.py | 10 +-- 2 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 tapir/shifts/tests/test_shifttemplateenddateview.py diff --git a/tapir/shifts/tests/test_shifttemplateenddateview.py b/tapir/shifts/tests/test_shifttemplateenddateview.py new file mode 100644 index 000000000..f014734bf --- /dev/null +++ b/tapir/shifts/tests/test_shifttemplateenddateview.py @@ -0,0 +1,88 @@ +import datetime + +from django.contrib.messages import get_messages +from django.urls import reverse +from django.utils import timezone + +from tapir.accounts.tests.factories.factories import TapirUserFactory +from tapir.shifts.tests.factories import ShiftTemplateFactory +from tapir.shifts.tests.utils import register_user_to_shift_template +from tapir.utils.tests_utils import TapirFactoryTestBase + + +class TestShiftTemplateEndView(TapirFactoryTestBase): + + def setUp(self): + super().setUp() + self.shift_template = ShiftTemplateFactory.create() + self.url = reverse( + "shifts:shift_template_set_end_date", kwargs={"pk": self.shift_template.pk} + ) + + def test_shiftTemplate_setEndDate_futureShiftsAfterEndDateAreCancelled(self): + self.login_as_employee() + + user = TapirUserFactory.create(is_in_member_office=False) + register_user_to_shift_template(self.client, user, self.shift_template) + + today = timezone.now().today() + shift_1 = self.shift_template.create_shift_if_necessary( + today + datetime.timedelta(days=7) + ) + shift_2 = self.shift_template.create_shift_if_necessary( + today + datetime.timedelta(days=14) + ) + shift_3 = self.shift_template.create_shift_if_necessary( + today + datetime.timedelta(days=21) + ) + + end_date = today + datetime.timedelta(days=14) + cancellation_reason = "Shift Template ended" + + response = self.client.post( + self.url, + { + "end_date": end_date.strftime("%Y-%m-%d"), + "cancellation_reason": cancellation_reason, + }, + ) + + self.assertRedirects( + response, + reverse( + "shifts:shift_template_detail", kwargs={"pk": self.shift_template.pk} + ), + ) + + self.shift_template.refresh_from_db() + shift_1.refresh_from_db() + shift_2.refresh_from_db() + shift_3.refresh_from_db() + + self.assertEqual(self.shift_template.end_date, end_date.date()) + + self.assertFalse(shift_1.cancelled) + self.assertFalse(shift_2.cancelled) + + self.assertTrue(shift_3.cancelled) + self.assertEqual(shift_3.cancelled_reason, cancellation_reason) + + # def test_shiftTemplate_sendEndDateAfterAllShifts_noShiftIsCancelled(self): + # self.login_as_employee() + # today = timezone.now().today() + # end_date = today + datetime.timedelta(days=365) + # cancellation_reason = "Shift Template ended" + # + # response = self.client.post( + # self.url, + # { + # "end_date": end_date.strftime("%Y-%m-%d"), + # "cancellation_reason": cancellation_reason, + # }, + # ) + # + # self.shift_template.refresh_from_db() + # self.assertEqual(self.shift_template.end_date, end_date.date()) + # + # msgs = list(get_messages(response.wsgi_request)) + # self.assertGreater(len(msgs), 0) diff --git a/tapir/shifts/views/views.py b/tapir/shifts/views/views.py index 8b61ffcc0..9dd185355 100644 --- a/tapir/shifts/views/views.py +++ b/tapir/shifts/views/views.py @@ -327,12 +327,12 @@ def form_valid(self, form): shift.cancelled_reason = cancellation_reason ShiftCancellationService.cancel(shift) - messages.success( - self.request, - _("Shift template was successfully cancelled"), - ) + messages.success( + self.request, + _("Shift template was successfully cancelled"), + ) - return response + return response class ShiftUserDataTable(django_tables2.Table): From 46547b9b0f2109daddf3309cca6358ebb7c71509 Mon Sep 17 00:00:00 2001 From: crosspolar <18083323+crosspolar@users.noreply.github.com> Date: Sat, 18 Apr 2026 09:12:44 +0200 Subject: [PATCH 04/14] test_createShiftForGroup_endDate_noShiftsCreatedPastEndDate --- .../test_create_shifts_for_group.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tapir/shifts/tests/services/shift_generator/test_create_shifts_for_group.py b/tapir/shifts/tests/services/shift_generator/test_create_shifts_for_group.py index f6fd77917..387dbaf10 100644 --- a/tapir/shifts/tests/services/shift_generator/test_create_shifts_for_group.py +++ b/tapir/shifts/tests/services/shift_generator/test_create_shifts_for_group.py @@ -113,3 +113,22 @@ def test_createShiftsForGroup_withoutHolidayCancellation_doesntCancelsHolidays( ) self.assertFalse(shift.cancelled) self.assertIsNone(shift.cancelled_reason) + + def test_createShiftForGroup_endDate_noShiftsCreatedPastEndDate(self): + group_a = ShiftTemplateGroup.objects.create(name="A") + + template_with_future_end_date = ShiftTemplateFactory.create( + group=group_a, end_date=datetime.date(2025, 11, 20) + ) + + # should be created + ShiftGenerator.create_shifts_for_group( + at_date=datetime.date(2025, 11, 10), group=group_a + ) + + # should not be created + ShiftGenerator.create_shifts_for_group( + at_date=datetime.date(2025, 11, 24), group=group_a + ) + + self.assertEqual(1, template_with_future_end_date.generated_shifts.count()) From ea0635dd05defb9d47d308396af0d6a5b8686f22 Mon Sep 17 00:00:00 2001 From: crosspolar <18083323+crosspolar@users.noreply.github.com> Date: Sat, 18 Apr 2026 09:42:26 +0200 Subject: [PATCH 05/14] fix test --- .../tests/test_shifttemplateenddateview.py | 57 +++++++++++-------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/tapir/shifts/tests/test_shifttemplateenddateview.py b/tapir/shifts/tests/test_shifttemplateenddateview.py index f014734bf..e198078af 100644 --- a/tapir/shifts/tests/test_shifttemplateenddateview.py +++ b/tapir/shifts/tests/test_shifttemplateenddateview.py @@ -3,6 +3,7 @@ from django.contrib.messages import get_messages from django.urls import reverse from django.utils import timezone +from django_extensions.jobs import weekly from tapir.accounts.tests.factories.factories import TapirUserFactory from tapir.shifts.tests.factories import ShiftTemplateFactory @@ -14,18 +15,22 @@ class TestShiftTemplateEndView(TapirFactoryTestBase): def setUp(self): super().setUp() - self.shift_template = ShiftTemplateFactory.create() + self.shift_template = ShiftTemplateFactory.create( + start_date=timezone.now().date(), weekday=0 + ) self.url = reverse( "shifts:shift_template_set_end_date", kwargs={"pk": self.shift_template.pk} ) - def test_shiftTemplate_setEndDate_futureShiftsAfterEndDateAreCancelled(self): + def test_shiftTemplate_setEndDateInBetween_futureShiftsAfterEndDateAreCancelled( + self, + ): self.login_as_employee() user = TapirUserFactory.create(is_in_member_office=False) register_user_to_shift_template(self.client, user, self.shift_template) - today = timezone.now().today() + today = timezone.now().date() shift_1 = self.shift_template.create_shift_if_necessary( today + datetime.timedelta(days=7) ) @@ -59,7 +64,7 @@ def test_shiftTemplate_setEndDate_futureShiftsAfterEndDateAreCancelled(self): shift_2.refresh_from_db() shift_3.refresh_from_db() - self.assertEqual(self.shift_template.end_date, end_date.date()) + self.assertEqual(self.shift_template.end_date, end_date) self.assertFalse(shift_1.cancelled) self.assertFalse(shift_2.cancelled) @@ -67,22 +72,28 @@ def test_shiftTemplate_setEndDate_futureShiftsAfterEndDateAreCancelled(self): self.assertTrue(shift_3.cancelled) self.assertEqual(shift_3.cancelled_reason, cancellation_reason) - # def test_shiftTemplate_sendEndDateAfterAllShifts_noShiftIsCancelled(self): - # self.login_as_employee() - # today = timezone.now().today() - # end_date = today + datetime.timedelta(days=365) - # cancellation_reason = "Shift Template ended" - # - # response = self.client.post( - # self.url, - # { - # "end_date": end_date.strftime("%Y-%m-%d"), - # "cancellation_reason": cancellation_reason, - # }, - # ) - # - # self.shift_template.refresh_from_db() - # self.assertEqual(self.shift_template.end_date, end_date.date()) - # - # msgs = list(get_messages(response.wsgi_request)) - # self.assertGreater(len(msgs), 0) + def test_shiftTemplate_sendEndDateAfterAllShifts_noShiftIsCancelled(self): + self.login_as_employee() + today = timezone.now().date() + end_date = today + datetime.timedelta(days=365) + cancellation_reason = "Shift Template ended" + shift = self.shift_template.create_shift_if_necessary( + today + datetime.timedelta(days=7) + ) + + response = self.client.post( + self.url, + { + "end_date": end_date.strftime("%Y-%m-%d"), + "cancellation_reason": cancellation_reason, + }, + ) + + self.shift_template.refresh_from_db() + shift.refresh_from_db() + self.assertEqual(self.shift_template.end_date, end_date) + + self.assertFalse(shift.cancelled) + + msgs = list(get_messages(response.wsgi_request)) + self.assertGreater(len(msgs), 0) From 5e756c0e8b85ba8288660d441df7458436a11275 Mon Sep 17 00:00:00 2001 From: crosspolar <18083323+crosspolar@users.noreply.github.com> Date: Sat, 18 Apr 2026 09:54:51 +0200 Subject: [PATCH 06/14] end_date should not be before start date --- tapir/shifts/forms.py | 8 +++++++ .../tests/test_shifttemplateenddateview.py | 21 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/tapir/shifts/forms.py b/tapir/shifts/forms.py index 0f16ea153..d454bc8de 100644 --- a/tapir/shifts/forms.py +++ b/tapir/shifts/forms.py @@ -471,6 +471,14 @@ def __init__(self, shift_template=None, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["end_date"].required = True + def clean_end_date(self): + if ( + self.cleaned_data["end_date"] + and self.cleaned_data["end_date"] < self.instance.start_date + ): + raise ValidationError(_("The end date must be later than the start date.")) + return self.cleaned_data["end_date"] + class CreateShiftAccountEntryForm(forms.ModelForm): class Meta: diff --git a/tapir/shifts/tests/test_shifttemplateenddateview.py b/tapir/shifts/tests/test_shifttemplateenddateview.py index e198078af..cc45960fe 100644 --- a/tapir/shifts/tests/test_shifttemplateenddateview.py +++ b/tapir/shifts/tests/test_shifttemplateenddateview.py @@ -97,3 +97,24 @@ def test_shiftTemplate_sendEndDateAfterAllShifts_noShiftIsCancelled(self): msgs = list(get_messages(response.wsgi_request)) self.assertGreater(len(msgs), 0) + + def test_shiftTemplate_sendEndDate_endDateBeforeStartDate_showsValidationError( + self, + ): + self.login_as_employee() + + end_date = self.shift_template.start_date - datetime.timedelta(days=7) + + response = self.client.post( + self.url, + { + "end_date": end_date.strftime("%Y-%m-%d"), + "cancellation_reason": "Test", + }, + ) + + self.assertEqual(response.status_code, 200) + self.assertIn("end_date", response.context["form"].errors) + + self.shift_template.refresh_from_db() + self.assertIsNone(self.shift_template.end_date) From 3db24b4d3ad09505817134c131e2acfe78bcc704 Mon Sep 17 00:00:00 2001 From: crosspolar <18083323+crosspolar@users.noreply.github.com> Date: Sat, 18 Apr 2026 09:55:22 +0200 Subject: [PATCH 07/14] translation --- .../locale/de/LC_MESSAGES/django.po | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/tapir/translations/locale/de/LC_MESSAGES/django.po b/tapir/translations/locale/de/LC_MESSAGES/django.po index e5998bd4e..137d692ee 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-04-18 07:38+0200\n" +"POT-Creation-Date: 2026-04-18 09:55+0200\n" "PO-Revision-Date: 2025-07-07 13:06+0000\n" "Last-Translator: Weblate Admin \n" "Language-Team: German \n" @@ -644,7 +644,7 @@ msgstr "Wird normalerweise leer gelassen. Das Datum kann in der Zukunft liegen, msgid "Number of shares to create" msgstr "Anzahl zu erstellender Anteile" -#: coop/forms.py:67 +#: coop/forms.py:67 shifts/forms.py:479 msgid "The end date must be later than the start date." msgstr "Das Enddatum muss später als das Start-Datum sein" @@ -2563,7 +2563,7 @@ msgstr "Hat Qualifikation" msgid "Does not have qualification" msgstr "Hat die Qualifikation nicht" -#: coop/views/shareowner.py:647 shifts/forms.py:790 +#: coop/views/shareowner.py:647 shifts/forms.py:798 msgid "ABCD Week" msgstr "ABCD-Woche" @@ -3038,78 +3038,78 @@ msgstr "Das ausgewählte Mitglied muss ein investierendes Mitglied sein." msgid "This member is registered to at least one ABCD shift. Please confirm the change of attendance mode with the checkbox below." msgstr "" -#: shifts/forms.py:463 shifts/forms.py:621 +#: shifts/forms.py:463 shifts/forms.py:629 msgid "Cancellation Reason" msgstr "Grund der Absage" -#: shifts/forms.py:510 +#: shifts/forms.py:518 msgid "I have read the warning about the cancelled attendances and confirm that the exemption should be created" msgstr "Ich habe die Warnung über die abgesagte Schicht-Anwesenheit gelesen und bestätige, dass die Befreiung erzeugt werden soll" -#: shifts/forms.py:517 +#: shifts/forms.py:525 msgid "I have read the warning about the cancelled ABCD attendances and confirm that the exemption should be created" msgstr "Ich habe die Warnung über die abgebrochene ABCD-Teilnahme gelesen und bestätige, dass die Befreiung erzeugt werden soll" -#: shifts/forms.py:575 +#: shifts/forms.py:583 #, python-format msgid "The user will be unregistered from the following ABCD shifts because the exemption is longer than %(number_of_cycles)s cycles: %(attendances_display)s " msgstr "Das Mitglied wird von den folgenden ABCD-Schichten abgemeldet, weil die Befreiung länger als %(number_of_cycles)s Schichtzyklen ist: %(attendances_display)s " -#: shifts/forms.py:596 +#: shifts/forms.py:604 msgid "This shift has been deleted. It is not possible to cancel it." msgstr "Diese Schicht wurde bereits gelöscht. Es ist nicht möglich diese abzusagen." -#: shifts/forms.py:607 shifts/templates/shifts/shift_detail.html:8 +#: shifts/forms.py:615 shifts/templates/shifts/shift_detail.html:8 #: shifts/templates/shifts/shift_detail.html:30 msgid "Shift" msgstr "Schicht" -#: shifts/forms.py:608 +#: shifts/forms.py:616 msgid "already cancelled" msgstr "bereits bgesagt" -#: shifts/forms.py:622 +#: shifts/forms.py:630 msgid "This reason will be applied to all cancelled shifts." msgstr "" -#: shifts/forms.py:650 +#: shifts/forms.py:658 msgid "I understand that updating this ABCD shift will update all the corresponding future shifts" msgstr "" -#: shifts/forms.py:669 +#: shifts/forms.py:677 msgid "ABCD-Week" msgstr "ABCD-Woche" -#: shifts/forms.py:673 +#: shifts/forms.py:681 msgid "Weekdays" msgstr "Wochentage" -#: shifts/forms.py:698 +#: shifts/forms.py:706 msgid "I understand that adding or editing a slot to this ABCD shift will affect all the corresponding future shifts" msgstr "" -#: shifts/forms.py:707 +#: shifts/forms.py:715 msgid "I understand that this will delete the shift exemption and create a membership pause" msgstr "" -#: shifts/forms.py:739 shifts/forms.py:795 shifts/views/views.py:425 +#: shifts/forms.py:747 shifts/forms.py:803 shifts/views/views.py:425 #: shifts/views/views.py:426 msgid "Shift changes you would like to be informed about" msgstr "Schicht-Änderungen, bei denen du informiert werden möchtest" -#: shifts/forms.py:784 shifts/templates/shifts/shift_template_detail.html:7 +#: shifts/forms.py:792 shifts/templates/shifts/shift_template_detail.html:7 #: shifts/templates/shifts/shift_template_detail.html:15 #: shifts/templates/shifts/user_shifts_overview_tag.html:31 #: shifts/templates/shifts/user_shifts_overview_tag.html:43 msgid "ABCD Shift" msgstr "ABCD-Schicht" -#: shifts/forms.py:801 +#: shifts/forms.py:809 #, python-format msgid "If weekdays or %(shift_template_group)s are selected, %(shift_templates)s may not be selected, and vice versa." msgstr "" -#: shifts/forms.py:805 +#: shifts/forms.py:813 #, python-format msgid "At least one of the fields (%(shift_templates)s, weekdays, or %(shift_template_group)s) must be selected." msgstr "" From 406fc370f3e44862281660004097807729688be7 Mon Sep 17 00:00:00 2001 From: crosspolar <18083323+crosspolar@users.noreply.github.com> Date: Sun, 14 Jun 2026 19:28:05 +0200 Subject: [PATCH 08/14] translation --- .../locale/de/LC_MESSAGES/django.po | 186 +++++++++++------- 1 file changed, 111 insertions(+), 75 deletions(-) diff --git a/tapir/translations/locale/de/LC_MESSAGES/django.po b/tapir/translations/locale/de/LC_MESSAGES/django.po index ce1f84ca4..f7c373652 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-14 19:27+0200\n" "PO-Revision-Date: 2025-07-07 13:06+0000\n" "Last-Translator: Weblate Admin \n" "Language-Team: German \n" @@ -343,7 +343,7 @@ msgstr "Benutzername bearbeiten" #: core/templates/core/featureflag_list.html:30 #: shifts/templates/shifts/shift_detail.html:61 #: shifts/templates/shifts/shift_template_detail.html:29 -#: shifts/templates/shifts/shift_template_detail.html:117 +#: shifts/templates/shifts/shift_template_detail.html:122 #: shifts/templates/shifts/user_shifts_overview_tag.html:14 msgid "Edit" msgstr "Bearbeiten" @@ -652,7 +652,7 @@ msgstr "Wird normalerweise leer gelassen. Das Datum kann in der Zukunft liegen, msgid "Number of shares to create" msgstr "Anzahl zu erstellender Anteile" -#: coop/forms.py:67 +#: coop/forms.py:67 shifts/forms.py:478 msgid "The end date must be later than the start date." msgstr "Das Enddatum muss später als das Start-Datum sein" @@ -1113,7 +1113,7 @@ msgstr "Bewerber*in erzeugen" #: shifts/templates/shifts/register_user_to_shift_slot.html:27 #: shifts/templates/shifts/register_user_to_shift_slot_template.html:26 #: shifts/templates/shifts/shift_detail.html:243 -#: shifts/templates/shifts/shift_template_detail.html:88 +#: shifts/templates/shifts/shift_template_detail.html:93 msgid "Register" msgstr "Anmelden" @@ -2089,6 +2089,7 @@ msgid "Submit" msgstr "Abschicken" #: coop/templates/coop/extra_share_request.html:92 +#: shifts/templates/shifts/shift_template_set_end_date.html:25 #: shifts/templates/shifts/user_shifts_overview_tag.html:177 msgid "Cancel" msgstr "Abmelden" @@ -2275,7 +2276,7 @@ msgstr "" " " #: coop/templates/coop/membershipresignation_detail.html:61 -#: shifts/models.py:535 +#: shifts/models.py:541 msgid "Cancellation reason" msgstr "Grund der Kündigung" @@ -2522,7 +2523,7 @@ msgstr "" " " #: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:56 -#: shifts/models.py:933 shifts/templates/shifts/shift_day_printable.html:214 +#: shifts/models.py:939 shifts/templates/shifts/shift_day_printable.html:214 #: shifts/templates/shifts/shift_day_printable.html:276 #: shifts/templates/shifts/shift_detail.html:298 #: shifts/templates/shifts/shift_detail_printable.html:51 @@ -2530,7 +2531,7 @@ msgid "Attended" msgstr "Teilgenommen" #: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:58 -#: shifts/models.py:932 +#: shifts/models.py:938 msgid "Pending" msgstr "Ausstehend" @@ -2703,7 +2704,7 @@ msgstr "Hat Qualifikation" msgid "Does not have qualification" msgstr "Hat die Qualifikation nicht" -#: coop/views/shareowner.py:656 shifts/forms.py:788 +#: coop/views/shareowner.py:656 shifts/forms.py:809 msgid "ABCD Week" msgstr "ABCD-Woche" @@ -2836,8 +2837,8 @@ msgstr "" msgid "List of all emails" msgstr "Liste alle E-Mails" -#: core/templates/core/email_list.html:39 shifts/models.py:502 -#: shifts/models.py:1071 shifts/templates/shifts/user_shift_account_log.html:29 +#: core/templates/core/email_list.html:39 shifts/models.py:508 +#: shifts/models.py:1077 shifts/templates/shifts/user_shift_account_log.html:29 msgid "Description" msgstr "Beschreibung" @@ -3182,86 +3183,86 @@ msgstr "Das ausgewählte Mitglied muss ein investierendes Mitglied sein." msgid "This member is registered to at least one ABCD shift. Please confirm the change of attendance mode with the checkbox below." msgstr "" -#: shifts/forms.py:496 +#: shifts/forms.py:462 shifts/forms.py:628 +msgid "Cancellation Reason" +msgstr "Grund der Absage" + +#: shifts/forms.py:517 msgid "I have read the warning about the cancelled attendances and confirm that the exemption should be created" msgstr "Ich habe die Warnung über die abgesagte Schicht-Anwesenheit gelesen und bestätige, dass die Befreiung erzeugt werden soll" -#: shifts/forms.py:503 +#: shifts/forms.py:524 msgid "I have read the warning about the cancelled ABCD attendances and confirm that the exemption should be created" msgstr "Ich habe die Warnung über die abgebrochene ABCD-Teilnahme gelesen und bestätige, dass die Befreiung erzeugt werden soll" -#: shifts/forms.py:561 +#: shifts/forms.py:582 #, python-format msgid "The user will be unregistered from the following ABCD shifts because the exemption is longer than %(number_of_cycles)s cycles: %(attendances_display)s " msgstr "Das Mitglied wird von den folgenden ABCD-Schichten abgemeldet, weil die Befreiung länger als %(number_of_cycles)s Schichtzyklen ist: %(attendances_display)s " -#: shifts/forms.py:582 +#: shifts/forms.py:603 msgid "This shift has been deleted. It is not possible to cancel it." msgstr "Diese Schicht wurde bereits gelöscht. Es ist nicht möglich diese abzusagen." -#: shifts/forms.py:593 shifts/templates/shifts/shift_detail.html:8 +#: shifts/forms.py:614 shifts/templates/shifts/shift_detail.html:8 #: shifts/templates/shifts/shift_detail.html:30 msgid "Shift" msgstr "Schicht" -#: shifts/forms.py:594 +#: shifts/forms.py:615 msgid "already cancelled" msgstr "bereits bgesagt" -#: shifts/forms.py:607 -msgid "Cancellation Reason" -msgstr "Grund der Absage" - -#: shifts/forms.py:608 +#: shifts/forms.py:629 msgid "This reason will be applied to all cancelled shifts." msgstr "" -#: shifts/forms.py:636 +#: shifts/forms.py:657 msgid "I understand that updating this ABCD shift will update all the corresponding future shifts" msgstr "" -#: shifts/forms.py:655 +#: shifts/forms.py:676 msgid "ABCD-Week" msgstr "ABCD-Woche" -#: shifts/forms.py:659 +#: shifts/forms.py:680 msgid "Weekdays" msgstr "Wochentage" -#: shifts/forms.py:684 +#: shifts/forms.py:705 msgid "I understand that adding or editing a slot to this ABCD shift will affect all the corresponding future shifts" msgstr "" -#: shifts/forms.py:693 +#: shifts/forms.py:714 msgid "I understand that this will delete the shift exemption and create a membership pause" msgstr "" -#: shifts/forms.py:725 shifts/forms.py:793 shifts/views/views.py:377 -#: shifts/views/views.py:378 +#: shifts/forms.py:746 shifts/forms.py:814 shifts/views/views.py:421 +#: shifts/views/views.py:422 msgid "Shift changes you would like to be informed about" msgstr "Schicht-Änderungen, bei denen du informiert werden möchtest" -#: shifts/forms.py:732 +#: shifts/forms.py:753 msgid "Notify me when these capabilities become available or unavailable" msgstr "" -#: shifts/forms.py:736 +#: shifts/forms.py:757 msgid "Get notified when someone with specific skills registers or unregisters" msgstr "" -#: shifts/forms.py:782 shifts/templates/shifts/shift_template_detail.html:7 +#: shifts/forms.py:803 shifts/templates/shifts/shift_template_detail.html:7 #: shifts/templates/shifts/shift_template_detail.html:15 #: shifts/templates/shifts/user_shifts_overview_tag.html:31 #: shifts/templates/shifts/user_shifts_overview_tag.html:43 msgid "ABCD Shift" msgstr "ABCD-Schicht" -#: shifts/forms.py:799 +#: shifts/forms.py:820 #, python-format msgid "If weekdays or %(shift_template_group)s are selected, %(shift_templates)s may not be selected, and vice versa." msgstr "" -#: shifts/forms.py:803 +#: shifts/forms.py:824 #, python-format msgid "At least one of the fields (%(shift_templates)s, weekdays, or %(shift_template_group)s) must be selected." msgstr "" @@ -3326,7 +3327,7 @@ msgstr "Mir ist klar, dass ich bei dieser Schicht möglicherweise schwere Gewich msgid "I understand that I may need to work high, for example up a ladder. I do not suffer from fear of heights." msgstr "Mir ist klar, dass ich möglicherweise in großer Höhe arbeiten muss, zum Beispiel auf einer Leiter. Ich leide nicht unter Höhenangst." -#: shifts/models.py:166 shifts/models.py:496 +#: shifts/models.py:166 shifts/models.py:502 msgid "If there are less members registered to a shift than that number, it will be highlighted in the shift calendar. The number of required attendances can't be higher than the slots in the resp. shift." msgstr "Wenn weniger Mitlieder als diese Nummer zur Schicht registriert sind, wird diese blau angezeigt. Die Anzahl der benltigten Mitglieder kann nicht höher sein als die Anzahl vorhandener Slots." @@ -3334,47 +3335,51 @@ msgstr "Wenn weniger Mitlieder als diese Nummer zur Schicht registriert sind, wi msgid "This determines from which date shifts should be generated from this ABCD shift." msgstr "" -#: shifts/models.py:181 shifts/models.py:510 +#: shifts/models.py:183 +msgid "All shifts after this date will be cancelled." +msgstr "" + +#: shifts/models.py:186 shifts/models.py:516 #: shifts/templates/shifts/shift_block_tag.html:11 msgid "Flexible time" msgstr "Zeit flexibel" -#: shifts/models.py:183 shifts/models.py:512 +#: shifts/models.py:188 shifts/models.py:518 msgid "If enabled, members who register for that shift can choose themselves the time where they come do their shift." msgstr "" -#: shifts/models.py:408 shifts/models.py:824 +#: shifts/models.py:414 shifts/models.py:830 #: shifts/templates/shifts/shift_detail.html:112 -#: shifts/templates/shifts/shift_template_detail.html:46 +#: shifts/templates/shifts/shift_template_detail.html:51 msgid "Chosen time" msgstr "Ausgewählte Uhrzeit" -#: shifts/models.py:410 +#: shifts/models.py:416 msgid "This shift lets you choose at what time you come during the day of the shift. In order to help organising the attendance, please specify when you expect to come.Setting or updating this field will set the time for all individual shifts generated from this ABCD shift.You can update the time of a single shift individually and at any time on the shift page." msgstr "" -#: shifts/models.py:494 +#: shifts/models.py:500 msgid "Number of required attendances" msgstr "Anzahl notwendiger Teilnehmender" -#: shifts/models.py:503 +#: shifts/models.py:509 msgid "Is shown on the shift page below the title" msgstr "" -#: shifts/models.py:523 shifts/models.py:529 +#: shifts/models.py:529 shifts/models.py:535 msgid "If 'flexible time' is enabled, then the time component is ignored" msgstr "" -#: shifts/models.py:826 +#: shifts/models.py:832 msgid "This shift lets you choose at what time you come during the day of the shift. In order to help organising the attendance, please specify when you expect to come." msgstr "Diese Schicht ermöglicht dir auszusuchen, wann du kommen magst. Um die Planung zu erleichtern, gib bitte deine erwartete Ankunftszeit an." -#: shifts/models.py:934 shifts/templates/shifts/shift_detail.html:308 +#: shifts/models.py:940 shifts/templates/shifts/shift_detail.html:308 #: shifts/templates/shifts/shift_detail_printable.html:52 msgid "Missed" msgstr "Nicht erschienen" -#: shifts/models.py:935 shifts/templates/shifts/shift_day_printable.html:216 +#: shifts/models.py:941 shifts/templates/shifts/shift_day_printable.html:216 #: shifts/templates/shifts/shift_day_printable.html:281 #: shifts/templates/shifts/shift_day_printable.html:283 #: shifts/templates/shifts/shift_detail.html:338 @@ -3382,58 +3387,58 @@ msgstr "Nicht erschienen" msgid "Excused" msgstr "Entschuldigt" -#: shifts/models.py:936 shifts/templates/shifts/shift_detail.html:346 +#: shifts/models.py:942 shifts/templates/shifts/shift_detail.html:346 msgid "Cancelled" msgstr "Abgesagt" -#: shifts/models.py:937 shifts/templates/shifts/shift_day_printable.html:264 +#: shifts/models.py:943 shifts/templates/shifts/shift_day_printable.html:264 #: shifts/templates/shifts/shift_detail.html:330 #: shifts/templates/shifts/shift_detail_printable.html:94 #: shifts/templates/shifts/shift_filters.html:83 msgid "Looking for a stand-in" msgstr "Sucht Vertretung" -#: shifts/models.py:970 +#: shifts/models.py:976 msgid "🏠 ABCD" msgstr "🏠 ABCD" -#: shifts/models.py:971 +#: shifts/models.py:977 msgid "✈ Flying" msgstr "✈ Fliegend" -#: shifts/models.py:972 +#: shifts/models.py:978 msgid "❄ Frozen" msgstr "❄ Eingefroren" -#: shifts/models.py:1003 +#: shifts/models.py:1009 msgid "Is frozen" msgstr "Ist eingefroren" -#: shifts/models.py:1177 +#: shifts/models.py:1183 msgid "Cycle start date" msgstr "Anfangsdatum" -#: shifts/models.py:1198 +#: shifts/models.py:1204 msgid "Shift is almost full, only one spot left." msgstr "Die Schicht ist fast voll, es ist nur noch ein Platz übrig." -#: shifts/models.py:1199 +#: shifts/models.py:1205 msgid "Shift is full now." msgstr "Die Schicht ist jetzt voll." -#: shifts/models.py:1200 +#: shifts/models.py:1206 msgid "The Shift is understaffed!" msgstr "Die Schicht ist jetzt unterbesetzt." -#: shifts/models.py:1201 +#: shifts/models.py:1207 msgid "Shift stable: not understaffed, not fully staffed." msgstr "Entwarnung. Die schicht ist nicht länger unterbesetzt, aber es noch Platz übrig" -#: shifts/models.py:1203 +#: shifts/models.py:1209 msgid "One new attendance or more registered, but the shift is neither understaffed nor full or almost full." msgstr "Ein Mitglied oder mehr hat sich registriert, aber die Schicht ist weder unterbesetzt noch (fast) voll" -#: shifts/models.py:1206 +#: shifts/models.py:1212 msgid "One attendance or more un-registered, but the shift is neither understaffed nor full or almost full." msgstr "Ein Mitglied oder mehr hat sich abgemeldet, aber die Schicht ist weder unterbesetzt noch (fast) voll" @@ -4256,7 +4261,7 @@ msgstr "Flexible Arbeitszeit nicht angegeben" #: shifts/templates/shifts/shift_day_printable.html:259 #: shifts/templates/shifts/shift_detail.html:139 #: shifts/templates/shifts/shift_detail_printable.html:90 -#: shifts/templates/shifts/shift_template_detail.html:68 +#: shifts/templates/shifts/shift_template_detail.html:73 msgid "Shift partner: " msgstr "Schicht-Partner: " @@ -4320,12 +4325,12 @@ msgid "Number" msgstr "Nummer" #: shifts/templates/shifts/shift_detail.html:106 -#: shifts/templates/shifts/shift_template_detail.html:42 +#: shifts/templates/shifts/shift_template_detail.html:47 msgid "Details" msgstr "Details" #: shifts/templates/shifts/shift_detail.html:107 -#: shifts/templates/shifts/shift_template_detail.html:44 +#: shifts/templates/shifts/shift_template_detail.html:49 msgid "Registered user" msgstr "Angemeldete*r Nutzer*in" @@ -4338,7 +4343,7 @@ msgid "Do you meet the requirements?" msgstr "Erfüllst du die Voraussetzungen?" #: shifts/templates/shifts/shift_detail.html:115 -#: shifts/templates/shifts/shift_template_detail.html:49 +#: shifts/templates/shifts/shift_template_detail.html:54 msgid "Member-Office actions" msgstr "Mitgliederbüro Aktionen" @@ -4444,7 +4449,7 @@ msgstr "" " " #: shifts/templates/shifts/shift_detail.html:271 -#: shifts/templates/shifts/shift_template_detail.html:99 +#: shifts/templates/shifts/shift_template_detail.html:104 msgid "Not specified" msgstr "" @@ -4573,23 +4578,29 @@ msgstr "" msgid "Duplicate" msgstr "Dopplung" -#: shifts/templates/shifts/shift_template_detail.html:38 +#: shifts/templates/shifts/shift_template_detail.html:34 +#, fuzzy +#| msgid "Pay out end date" +msgid "Set end date" +msgstr "Auszahlungsende" + +#: shifts/templates/shifts/shift_template_detail.html:43 msgid "List of slots for this ABCD shifts" msgstr "Liste des Slots für diese ABCD-Schicht" -#: shifts/templates/shifts/shift_template_detail.html:43 +#: shifts/templates/shifts/shift_template_detail.html:48 msgid "Requirements" msgstr "" -#: shifts/templates/shifts/shift_template_detail.html:77 +#: shifts/templates/shifts/shift_template_detail.html:82 msgid "Unregister" msgstr "Abmelden" -#: shifts/templates/shifts/shift_template_detail.html:126 +#: shifts/templates/shifts/shift_template_detail.html:131 msgid "Future generated Shifts" msgstr "Zukünftige erstellte Schichten" -#: shifts/templates/shifts/shift_template_detail.html:136 +#: shifts/templates/shifts/shift_template_detail.html:141 msgid "Past generated Shifts" msgstr "Vergangene Schichten" @@ -4628,6 +4639,27 @@ msgstr "" msgid "Calendar of ABCD shifts" msgstr "Kalender der ABCD-Schichten" +#: shifts/templates/shifts/shift_template_set_end_date.html:7 +#: shifts/templates/shifts/shift_template_set_end_date.html:11 +#, fuzzy +#| msgid "Pay out end date" +msgid "Set end date for" +msgstr "Auszahlungsende" + +#: shifts/templates/shifts/shift_template_set_end_date.html:17 +msgid "Warning" +msgstr "" + +#: shifts/templates/shifts/shift_template_set_end_date.html:18 +msgid "All shifts generated from this ABCD-shift after the selected date will be cancelled. Registered members will be notified." +msgstr "" + +#: shifts/templates/shifts/shift_template_set_end_date.html:22 +#, fuzzy +#| msgid "Set shift attendance to" +msgid "Set end date and cancel shifts" +msgstr "Ändere den Schichtstatus zu" + #: shifts/templates/shifts/shiftexemption_list.html:38 msgid "Create shift exemption" msgstr "Schicht-Befreiung erzeugen" @@ -4659,7 +4691,7 @@ msgid "Recurring Shift Watches" msgstr "Wiederholende Schichtbeobachtungen" #: shifts/templates/shifts/shiftwatch_overview.html:25 -#: shifts/views/views.py:422 +#: shifts/views/views.py:466 msgid "Create a rule for recurring Shift Watches" msgstr "Erstelle eine Regel für sich wiederholende Schichtbeobachtungen" @@ -4993,7 +5025,7 @@ msgid "No watched shifts" msgstr "Keine beobachteten Schichten" #: shifts/templatetags/shifts.py:69 shifts/templatetags/shifts.py:174 -#: shifts/views/views.py:150 +#: shifts/views/views.py:152 msgid "General" msgstr "Allgemein" @@ -5092,27 +5124,31 @@ msgstr "Es konnte keine vollendete Schicht gefunden werden, die als Solidarität msgid "Solidarity Shift given. Account Balance debited with -1." msgstr "Die Solidaritätsschicht wurde vergeben. Von deinem Kontostand wird nun eine Schicht abgezogen." -#: shifts/views/views.py:130 shifts/views/views.py:135 +#: shifts/views/views.py:132 shifts/views/views.py:137 #, python-format msgid "Edit user shift data: %(name)s" msgstr "Bearbeite Nutzer*in-Schichtdaten: %(name)s" -#: shifts/views/views.py:203 +#: shifts/views/views.py:205 #, python-format msgid "Shift account: %(name)s" msgstr "Schichtkonto-Protokoll für: %(name)s" -#: shifts/views/views.py:209 +#: shifts/views/views.py:211 #, fuzzy, python-format #| msgid "Create manual shift account entry for: %(link)s" msgid "Create manual shift account entry for: %(link)s" msgstr "Erzeuge Schicht-Kontoeintrag für: %(link)s" -#: shifts/views/views.py:360 +#: shifts/views/views.py:328 +msgid "Shift template was successfully cancelled" +msgstr "" + +#: shifts/views/views.py:404 msgid "Frozen statuses updated." msgstr "" -#: shifts/views/views.py:425 +#: shifts/views/views.py:469 #, python-format msgid "Please select either %(shift_template_group)s and/or weekdays, or alternatively %(shift_templates)s." msgstr "" From 0fad0d059f04e99aeac7c61ef4e6accc3c97ed93 Mon Sep 17 00:00:00 2001 From: crosspolar <18083323+crosspolar@users.noreply.github.com> Date: Sun, 14 Jun 2026 19:38:12 +0200 Subject: [PATCH 09/14] fix migration --- ...ifttemplate_end_date.py => 0076_shifttemplate_end_date.py} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename tapir/shifts/migrations/{0075_shifttemplate_end_date.py => 0076_shifttemplate_end_date.py} (78%) diff --git a/tapir/shifts/migrations/0075_shifttemplate_end_date.py b/tapir/shifts/migrations/0076_shifttemplate_end_date.py similarity index 78% rename from tapir/shifts/migrations/0075_shifttemplate_end_date.py rename to tapir/shifts/migrations/0076_shifttemplate_end_date.py index f0bee3db1..c4d80047b 100644 --- a/tapir/shifts/migrations/0075_shifttemplate_end_date.py +++ b/tapir/shifts/migrations/0076_shifttemplate_end_date.py @@ -1,4 +1,4 @@ -# Generated by Django 5.2.13 on 2026-04-17 16:42 +# Generated by Django 5.2.15 on 2026-06-14 17:37 from django.db import migrations, models @@ -6,7 +6,7 @@ class Migration(migrations.Migration): dependencies = [ - ("shifts", "0074_alter_shift_num_required_attendances"), + ("shifts", "0075_shiftwatch_watched_capabilities"), ] operations = [ From 61aeb933b7398427fce1b349488f8a1f1f9854fa Mon Sep 17 00:00:00 2001 From: crosspolar <18083323+crosspolar@users.noreply.github.com> Date: Fri, 10 Jul 2026 17:05:01 +0200 Subject: [PATCH 10/14] transl --- .../shifts/templates/shifts/shift_detail.html | 15 +- .../locale/de/LC_MESSAGES/django.po | 191 +++++++++++------- 2 files changed, 123 insertions(+), 83 deletions(-) diff --git a/tapir/shifts/templates/shifts/shift_detail.html b/tapir/shifts/templates/shifts/shift_detail.html index bb674f208..2c0fd8ca8 100644 --- a/tapir/shifts/templates/shifts/shift_detail.html +++ b/tapir/shifts/templates/shifts/shift_detail.html @@ -234,12 +234,17 @@
#{{ forloop.counter }}
{% elif not slot.is_occupied %} {% blocktranslate asvar self_register_tooltip %}You can only register yourself - for a shift if:
- -You are not registered to another slot in that shift
+ for a shift if: +
+ -You are not registered to another slot in that shift +
-You have the required qualification (if you want to get a - qualification, contact the member office)
- -The shift is in the future
- -The shift is not cancelled (holidays...)
+ qualification, contact the member office) +
+ -The shift is in the future +
+ -The shift is not cancelled (holidays...) +
{% endblocktranslate %} {% autoescape off %} diff --git a/tapir/translations/locale/de/LC_MESSAGES/django.po b/tapir/translations/locale/de/LC_MESSAGES/django.po index 0e17400fd..e33261ffd 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-07-06 20:45+0200\n" +"POT-Creation-Date: 2026-07-10 17:03+0200\n" "PO-Revision-Date: 2025-07-07 13:06+0000\n" "Last-Translator: Weblate Admin \n" "Language-Team: German \n" @@ -343,7 +343,7 @@ msgstr "Benutzername bearbeiten" #: core/templates/core/featureflag_list.html:30 #: shifts/templates/shifts/shift_detail.html:65 #: shifts/templates/shifts/shift_template_detail.html:29 -#: shifts/templates/shifts/shift_template_detail.html:117 +#: shifts/templates/shifts/shift_template_detail.html:122 #: shifts/templates/shifts/user_shifts_overview_tag.html:14 msgid "Edit" msgstr "Bearbeiten" @@ -652,7 +652,7 @@ msgstr "Wird normalerweise leer gelassen. Das Datum kann in der Zukunft liegen, msgid "Number of shares to create" msgstr "Anzahl zu erstellender Anteile" -#: coop/forms.py:67 +#: coop/forms.py:67 shifts/forms.py:478 msgid "The end date must be later than the start date." msgstr "Das Enddatum muss später als das Start-Datum sein" @@ -1113,7 +1113,7 @@ msgstr "Bewerber*in erzeugen" #: shifts/templates/shifts/register_user_to_shift_slot.html:27 #: shifts/templates/shifts/register_user_to_shift_slot_template.html:26 #: shifts/templates/shifts/shift_detail.html:249 -#: shifts/templates/shifts/shift_template_detail.html:88 +#: shifts/templates/shifts/shift_template_detail.html:93 msgid "Register" msgstr "Anmelden" @@ -2089,6 +2089,7 @@ msgid "Submit" msgstr "Abschicken" #: coop/templates/coop/extra_share_request.html:92 +#: shifts/templates/shifts/shift_template_set_end_date.html:25 #: shifts/templates/shifts/user_shifts_overview_tag.html:177 msgid "Cancel" msgstr "Abmelden" @@ -2275,7 +2276,7 @@ msgstr "" " " #: coop/templates/coop/membershipresignation_detail.html:61 -#: shifts/models.py:535 +#: shifts/models.py:541 msgid "Cancellation reason" msgstr "Grund der Kündigung" @@ -2522,7 +2523,7 @@ msgstr "" " " #: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:56 -#: shifts/models.py:933 shifts/templates/shifts/shift_day_printable.html:214 +#: shifts/models.py:939 shifts/templates/shifts/shift_day_printable.html:214 #: shifts/templates/shifts/shift_day_printable.html:276 #: shifts/templates/shifts/shift_detail.html:304 #: shifts/templates/shifts/shift_detail_printable.html:51 @@ -2530,7 +2531,7 @@ msgid "Attended" msgstr "Teilgenommen" #: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:58 -#: shifts/models.py:932 +#: shifts/models.py:938 msgid "Pending" msgstr "Ausstehend" @@ -2703,7 +2704,7 @@ msgstr "Hat Qualifikation" msgid "Does not have qualification" msgstr "Hat die Qualifikation nicht" -#: coop/views/shareowner.py:656 shifts/forms.py:788 +#: coop/views/shareowner.py:656 shifts/forms.py:809 msgid "ABCD Week" msgstr "ABCD-Woche" @@ -2836,8 +2837,8 @@ msgstr "" msgid "List of all emails" msgstr "Liste alle E-Mails" -#: core/templates/core/email_list.html:39 shifts/models.py:502 -#: shifts/models.py:1071 shifts/templates/shifts/user_shift_account_log.html:29 +#: core/templates/core/email_list.html:39 shifts/models.py:508 +#: shifts/models.py:1077 shifts/templates/shifts/user_shift_account_log.html:29 msgid "Description" msgstr "Beschreibung" @@ -3190,86 +3191,86 @@ msgstr "Das ausgewählte Mitglied muss ein investierendes Mitglied sein." msgid "This member is registered to at least one ABCD shift. Please confirm the change of attendance mode with the checkbox below." msgstr "" -#: shifts/forms.py:496 +#: shifts/forms.py:462 shifts/forms.py:628 +msgid "Cancellation Reason" +msgstr "Grund der Absage" + +#: shifts/forms.py:517 msgid "I have read the warning about the cancelled attendances and confirm that the exemption should be created" msgstr "Ich habe die Warnung über die abgesagte Schicht-Anwesenheit gelesen und bestätige, dass die Befreiung erzeugt werden soll" -#: shifts/forms.py:503 +#: shifts/forms.py:524 msgid "I have read the warning about the cancelled ABCD attendances and confirm that the exemption should be created" msgstr "Ich habe die Warnung über die abgebrochene ABCD-Teilnahme gelesen und bestätige, dass die Befreiung erzeugt werden soll" -#: shifts/forms.py:561 +#: shifts/forms.py:582 #, python-format msgid "The user will be unregistered from the following ABCD shifts because the exemption is longer than %(number_of_cycles)s cycles: %(attendances_display)s " msgstr "Das Mitglied wird von den folgenden ABCD-Schichten abgemeldet, weil die Befreiung länger als %(number_of_cycles)s Schichtzyklen ist: %(attendances_display)s " -#: shifts/forms.py:582 +#: shifts/forms.py:603 msgid "This shift has been deleted. It is not possible to cancel it." msgstr "Diese Schicht wurde bereits gelöscht. Es ist nicht möglich diese abzusagen." -#: shifts/forms.py:593 shifts/templates/shifts/shift_detail.html:8 +#: shifts/forms.py:614 shifts/templates/shifts/shift_detail.html:8 #: shifts/templates/shifts/shift_detail.html:30 msgid "Shift" msgstr "Schicht" -#: shifts/forms.py:594 +#: shifts/forms.py:615 msgid "already cancelled" msgstr "bereits bgesagt" -#: shifts/forms.py:607 -msgid "Cancellation Reason" -msgstr "Grund der Absage" - -#: shifts/forms.py:608 +#: shifts/forms.py:629 msgid "This reason will be applied to all cancelled shifts." msgstr "" -#: shifts/forms.py:636 +#: shifts/forms.py:657 msgid "I understand that updating this ABCD shift will update all the corresponding future shifts" msgstr "" -#: shifts/forms.py:655 +#: shifts/forms.py:676 msgid "ABCD-Week" msgstr "ABCD-Woche" -#: shifts/forms.py:659 +#: shifts/forms.py:680 msgid "Weekdays" msgstr "Wochentage" -#: shifts/forms.py:684 +#: shifts/forms.py:705 msgid "I understand that adding or editing a slot to this ABCD shift will affect all the corresponding future shifts" msgstr "" -#: shifts/forms.py:693 +#: shifts/forms.py:714 msgid "I understand that this will delete the shift exemption and create a membership pause" msgstr "" -#: shifts/forms.py:725 shifts/forms.py:793 shifts/views/views.py:419 -#: shifts/views/views.py:420 +#: shifts/forms.py:746 shifts/forms.py:814 shifts/views/views.py:463 +#: shifts/views/views.py:464 msgid "Shift changes you would like to be informed about" msgstr "Schicht-Änderungen, bei denen du informiert werden möchtest" -#: shifts/forms.py:732 +#: shifts/forms.py:753 msgid "Notify me when these capabilities become available or unavailable" msgstr "" -#: shifts/forms.py:736 +#: shifts/forms.py:757 msgid "Get notified when someone with specific skills registers or unregisters" msgstr "" -#: shifts/forms.py:782 shifts/templates/shifts/shift_template_detail.html:7 +#: shifts/forms.py:803 shifts/templates/shifts/shift_template_detail.html:7 #: shifts/templates/shifts/shift_template_detail.html:15 #: shifts/templates/shifts/user_shifts_overview_tag.html:31 #: shifts/templates/shifts/user_shifts_overview_tag.html:43 msgid "ABCD Shift" msgstr "ABCD-Schicht" -#: shifts/forms.py:799 +#: shifts/forms.py:820 #, python-format msgid "If weekdays or %(shift_template_group)s are selected, %(shift_templates)s may not be selected, and vice versa." msgstr "" -#: shifts/forms.py:803 +#: shifts/forms.py:824 #, python-format msgid "At least one of the fields (%(shift_templates)s, weekdays, or %(shift_template_group)s) must be selected." msgstr "" @@ -3334,7 +3335,7 @@ msgstr "Mir ist klar, dass ich bei dieser Schicht möglicherweise schwere Gewich msgid "I understand that I may need to work high, for example up a ladder. I do not suffer from fear of heights." msgstr "Mir ist klar, dass ich möglicherweise in großer Höhe arbeiten muss, zum Beispiel auf einer Leiter. Ich leide nicht unter Höhenangst." -#: shifts/models.py:166 shifts/models.py:496 +#: shifts/models.py:166 shifts/models.py:502 msgid "If there are less members registered to a shift than that number, it will be highlighted in the shift calendar. The number of required attendances can't be higher than the slots in the resp. shift." msgstr "Wenn weniger Mitlieder als diese Nummer zur Schicht registriert sind, wird diese blau angezeigt. Die Anzahl der benltigten Mitglieder kann nicht höher sein als die Anzahl vorhandener Slots." @@ -3342,47 +3343,51 @@ msgstr "Wenn weniger Mitlieder als diese Nummer zur Schicht registriert sind, wi msgid "This determines from which date shifts should be generated from this ABCD shift." msgstr "" -#: shifts/models.py:181 shifts/models.py:510 +#: shifts/models.py:183 +msgid "All shifts after this date will be cancelled." +msgstr "" + +#: shifts/models.py:186 shifts/models.py:516 #: shifts/templates/shifts/shift_block_tag.html:10 msgid "Flexible time" msgstr "Zeit flexibel" -#: shifts/models.py:183 shifts/models.py:512 +#: shifts/models.py:188 shifts/models.py:518 msgid "If enabled, members who register for that shift can choose themselves the time where they come do their shift." msgstr "" -#: shifts/models.py:408 shifts/models.py:824 +#: shifts/models.py:414 shifts/models.py:830 #: shifts/templates/shifts/shift_detail.html:118 -#: shifts/templates/shifts/shift_template_detail.html:46 +#: shifts/templates/shifts/shift_template_detail.html:51 msgid "Chosen time" msgstr "Ausgewählte Uhrzeit" -#: shifts/models.py:410 +#: shifts/models.py:416 msgid "This shift lets you choose at what time you come during the day of the shift. In order to help organising the attendance, please specify when you expect to come.Setting or updating this field will set the time for all individual shifts generated from this ABCD shift.You can update the time of a single shift individually and at any time on the shift page." msgstr "" -#: shifts/models.py:494 +#: shifts/models.py:500 msgid "Number of required attendances" msgstr "Anzahl notwendiger Teilnehmender" -#: shifts/models.py:503 +#: shifts/models.py:509 msgid "Is shown on the shift page below the title" msgstr "" -#: shifts/models.py:523 shifts/models.py:529 +#: shifts/models.py:529 shifts/models.py:535 msgid "If 'flexible time' is enabled, then the time component is ignored" msgstr "" -#: shifts/models.py:826 +#: shifts/models.py:832 msgid "This shift lets you choose at what time you come during the day of the shift. In order to help organising the attendance, please specify when you expect to come." msgstr "Diese Schicht ermöglicht dir auszusuchen, wann du kommen magst. Um die Planung zu erleichtern, gib bitte deine erwartete Ankunftszeit an." -#: shifts/models.py:934 shifts/templates/shifts/shift_detail.html:314 +#: shifts/models.py:940 shifts/templates/shifts/shift_detail.html:314 #: shifts/templates/shifts/shift_detail_printable.html:52 msgid "Missed" msgstr "Nicht erschienen" -#: shifts/models.py:935 shifts/templates/shifts/shift_day_printable.html:216 +#: shifts/models.py:941 shifts/templates/shifts/shift_day_printable.html:216 #: shifts/templates/shifts/shift_day_printable.html:281 #: shifts/templates/shifts/shift_day_printable.html:283 #: shifts/templates/shifts/shift_detail.html:344 @@ -3390,58 +3395,58 @@ msgstr "Nicht erschienen" msgid "Excused" msgstr "Entschuldigt" -#: shifts/models.py:936 shifts/templates/shifts/shift_detail.html:352 +#: shifts/models.py:942 shifts/templates/shifts/shift_detail.html:352 msgid "Cancelled" msgstr "Abgesagt" -#: shifts/models.py:937 shifts/templates/shifts/shift_day_printable.html:264 +#: shifts/models.py:943 shifts/templates/shifts/shift_day_printable.html:264 #: shifts/templates/shifts/shift_detail.html:336 #: shifts/templates/shifts/shift_detail_printable.html:94 #: shifts/templates/shifts/shift_filters.html:83 msgid "Looking for a stand-in" msgstr "Sucht Vertretung" -#: shifts/models.py:970 +#: shifts/models.py:976 msgid "🏠 ABCD" msgstr "🏠 ABCD" -#: shifts/models.py:971 +#: shifts/models.py:977 msgid "✈ Flying" msgstr "✈ Fliegend" -#: shifts/models.py:972 +#: shifts/models.py:978 msgid "❄ Frozen" msgstr "❄ Eingefroren" -#: shifts/models.py:1003 +#: shifts/models.py:1009 msgid "Is frozen" msgstr "Ist eingefroren" -#: shifts/models.py:1177 +#: shifts/models.py:1183 msgid "Cycle start date" msgstr "Anfangsdatum" -#: shifts/models.py:1198 +#: shifts/models.py:1204 msgid "Shift is almost full, only one spot left." msgstr "Die Schicht ist fast voll, es ist nur noch ein Platz übrig." -#: shifts/models.py:1199 +#: shifts/models.py:1205 msgid "Shift is full now." msgstr "Die Schicht ist jetzt voll." -#: shifts/models.py:1200 +#: shifts/models.py:1206 msgid "The Shift is understaffed!" msgstr "Die Schicht ist jetzt unterbesetzt." -#: shifts/models.py:1201 +#: shifts/models.py:1207 msgid "Shift stable: not understaffed, not fully staffed." msgstr "Entwarnung. Die schicht ist nicht länger unterbesetzt, aber es noch Platz übrig" -#: shifts/models.py:1203 +#: shifts/models.py:1209 msgid "One new attendance or more registered, but the shift is neither understaffed nor full or almost full." msgstr "Ein Mitglied oder mehr hat sich registriert, aber die Schicht ist weder unterbesetzt noch (fast) voll" -#: shifts/models.py:1206 +#: shifts/models.py:1212 msgid "One attendance or more un-registered, but the shift is neither understaffed nor full or almost full." msgstr "Ein Mitglied oder mehr hat sich abgemeldet, aber die Schicht ist weder unterbesetzt noch (fast) voll" @@ -4306,7 +4311,7 @@ msgstr "Flexible Arbeitszeit nicht angegeben" #: shifts/templates/shifts/shift_day_printable.html:259 #: shifts/templates/shifts/shift_detail.html:145 #: shifts/templates/shifts/shift_detail_printable.html:90 -#: shifts/templates/shifts/shift_template_detail.html:68 +#: shifts/templates/shifts/shift_template_detail.html:73 msgid "Shift partner: " msgstr "Schicht-Partner: " @@ -4370,12 +4375,12 @@ msgid "Number" msgstr "Nummer" #: shifts/templates/shifts/shift_detail.html:112 -#: shifts/templates/shifts/shift_template_detail.html:42 +#: shifts/templates/shifts/shift_template_detail.html:47 msgid "Details" msgstr "Details" #: shifts/templates/shifts/shift_detail.html:113 -#: shifts/templates/shifts/shift_template_detail.html:44 +#: shifts/templates/shifts/shift_template_detail.html:49 msgid "Registered user" msgstr "Angemeldete*r Nutzer*in" @@ -4388,7 +4393,7 @@ msgid "Do you meet the requirements?" msgstr "Erfüllst du die Voraussetzungen?" #: shifts/templates/shifts/shift_detail.html:121 -#: shifts/templates/shifts/shift_template_detail.html:49 +#: shifts/templates/shifts/shift_template_detail.html:54 msgid "Member-Office actions" msgstr "Mitgliederbüro Aktionen" @@ -4494,7 +4499,7 @@ msgstr "" " " #: shifts/templates/shifts/shift_detail.html:277 -#: shifts/templates/shifts/shift_template_detail.html:99 +#: shifts/templates/shifts/shift_template_detail.html:104 msgid "Not specified" msgstr "" @@ -4623,23 +4628,29 @@ msgstr "" msgid "Duplicate" msgstr "Dopplung" -#: shifts/templates/shifts/shift_template_detail.html:38 +#: shifts/templates/shifts/shift_template_detail.html:34 +#, fuzzy +#| msgid "Pay out end date" +msgid "Set end date" +msgstr "Auszahlungsende" + +#: shifts/templates/shifts/shift_template_detail.html:43 msgid "List of slots for this ABCD shifts" msgstr "Liste des Slots für diese ABCD-Schicht" -#: shifts/templates/shifts/shift_template_detail.html:43 +#: shifts/templates/shifts/shift_template_detail.html:48 msgid "Requirements" msgstr "" -#: shifts/templates/shifts/shift_template_detail.html:77 +#: shifts/templates/shifts/shift_template_detail.html:82 msgid "Unregister" msgstr "Abmelden" -#: shifts/templates/shifts/shift_template_detail.html:126 +#: shifts/templates/shifts/shift_template_detail.html:131 msgid "Future generated Shifts" msgstr "Zukünftige erstellte Schichten" -#: shifts/templates/shifts/shift_template_detail.html:136 +#: shifts/templates/shifts/shift_template_detail.html:141 msgid "Past generated Shifts" msgstr "Vergangene Schichten" @@ -4678,6 +4689,27 @@ msgstr "" msgid "Calendar of ABCD shifts" msgstr "Kalender der ABCD-Schichten" +#: shifts/templates/shifts/shift_template_set_end_date.html:7 +#: shifts/templates/shifts/shift_template_set_end_date.html:11 +#, fuzzy +#| msgid "Pay out end date" +msgid "Set end date for" +msgstr "Auszahlungsende" + +#: shifts/templates/shifts/shift_template_set_end_date.html:17 +msgid "Warning" +msgstr "" + +#: shifts/templates/shifts/shift_template_set_end_date.html:18 +msgid "All shifts generated from this ABCD-shift after the selected date will be cancelled. Registered members will be notified." +msgstr "" + +#: shifts/templates/shifts/shift_template_set_end_date.html:22 +#, fuzzy +#| msgid "Set shift attendance to" +msgid "Set end date and cancel shifts" +msgstr "Ändere den Schichtstatus zu" + #: shifts/templates/shifts/shiftexemption_list.html:38 msgid "Create shift exemption" msgstr "Schicht-Befreiung erzeugen" @@ -4709,7 +4741,7 @@ msgid "Recurring Shift Watches" msgstr "Wiederholende Schichtbeobachtungen" #: shifts/templates/shifts/shiftwatch_overview.html:25 -#: shifts/views/views.py:464 +#: shifts/views/views.py:508 msgid "Create a rule for recurring Shift Watches" msgstr "Erstelle eine Regel für sich wiederholende Schichtbeobachtungen" @@ -5043,7 +5075,7 @@ msgid "No watched shifts" msgstr "Keine beobachteten Schichten" #: shifts/templatetags/shifts.py:69 shifts/templatetags/shifts.py:174 -#: shifts/views/views.py:150 +#: shifts/views/views.py:152 msgid "General" msgstr "Allgemein" @@ -5142,27 +5174,33 @@ msgstr "Es konnte keine vollendete Schicht gefunden werden, die als Solidarität msgid "Solidarity Shift given. Account Balance debited with -1." msgstr "Die Solidaritätsschicht wurde vergeben. Von deinem Kontostand wird nun eine Schicht abgezogen." -#: shifts/views/views.py:130 shifts/views/views.py:135 +#: shifts/views/views.py:132 shifts/views/views.py:137 #, python-format msgid "Edit user shift data: %(name)s" msgstr "Bearbeite Nutzer*in-Schichtdaten: %(name)s" -#: shifts/views/views.py:203 +#: shifts/views/views.py:205 #, python-format msgid "Shift account: %(name)s" msgstr "Schichtkonto-Protokoll für: %(name)s" -#: shifts/views/views.py:209 +#: shifts/views/views.py:211 #, fuzzy, python-format #| msgid "Create manual shift account entry for: %(link)s" msgid "Create manual shift account entry for: %(link)s" msgstr "Erzeuge Schicht-Kontoeintrag für: %(link)s" -#: shifts/views/views.py:402 +#: shifts/views/views.py:370 +#, fuzzy +#| msgid "Shift attendance cancelled" +msgid "Shift template was successfully cancelled" +msgstr "Schicht" + +#: shifts/views/views.py:446 msgid "Frozen statuses updated." msgstr "" -#: shifts/views/views.py:467 +#: shifts/views/views.py:511 #, python-format msgid "Please select either %(shift_template_group)s and/or weekdays, or alternatively %(shift_templates)s." msgstr "" @@ -6625,9 +6663,6 @@ msgstr "%(name)s hat an dem Willkommenstreffen noch nicht teilgenommen. Stelle s #~ " Das Mitgliederbüro\n" #~ "

" -#~ msgid "Shift attendance cancelled" -#~ msgstr "Schicht" - #~ msgid "Buy" #~ msgstr "Kaufen" From 0f3de75c360f18ecfdf75f3bd977fc51cf008b9f Mon Sep 17 00:00:00 2001 From: crosspolar <18083323+crosspolar@users.noreply.github.com> Date: Fri, 10 Jul 2026 17:08:08 +0200 Subject: [PATCH 11/14] transl --- .../locale/de/LC_MESSAGES/django.po | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/tapir/translations/locale/de/LC_MESSAGES/django.po b/tapir/translations/locale/de/LC_MESSAGES/django.po index e33261ffd..1376e0b6c 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-07-10 17:03+0200\n" +"POT-Creation-Date: 2026-07-10 17:08+0200\n" "PO-Revision-Date: 2025-07-07 13:06+0000\n" "Last-Translator: Weblate Admin \n" "Language-Team: German \n" @@ -1112,7 +1112,7 @@ msgstr "Bewerber*in erzeugen" #: coop/templates/coop/draftuser_register_form.html:29 #: shifts/templates/shifts/register_user_to_shift_slot.html:27 #: shifts/templates/shifts/register_user_to_shift_slot_template.html:26 -#: shifts/templates/shifts/shift_detail.html:249 +#: shifts/templates/shifts/shift_detail.html:254 #: shifts/templates/shifts/shift_template_detail.html:93 msgid "Register" msgstr "Anmelden" @@ -2525,7 +2525,7 @@ msgstr "" #: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:56 #: shifts/models.py:939 shifts/templates/shifts/shift_day_printable.html:214 #: shifts/templates/shifts/shift_day_printable.html:276 -#: shifts/templates/shifts/shift_detail.html:304 +#: shifts/templates/shifts/shift_detail.html:309 #: shifts/templates/shifts/shift_detail_printable.html:51 msgid "Attended" msgstr "Teilgenommen" @@ -3382,7 +3382,7 @@ msgstr "" msgid "This shift lets you choose at what time you come during the day of the shift. In order to help organising the attendance, please specify when you expect to come." msgstr "Diese Schicht ermöglicht dir auszusuchen, wann du kommen magst. Um die Planung zu erleichtern, gib bitte deine erwartete Ankunftszeit an." -#: shifts/models.py:940 shifts/templates/shifts/shift_detail.html:314 +#: shifts/models.py:940 shifts/templates/shifts/shift_detail.html:319 #: shifts/templates/shifts/shift_detail_printable.html:52 msgid "Missed" msgstr "Nicht erschienen" @@ -3390,17 +3390,17 @@ msgstr "Nicht erschienen" #: shifts/models.py:941 shifts/templates/shifts/shift_day_printable.html:216 #: shifts/templates/shifts/shift_day_printable.html:281 #: shifts/templates/shifts/shift_day_printable.html:283 -#: shifts/templates/shifts/shift_detail.html:344 +#: shifts/templates/shifts/shift_detail.html:349 #: shifts/templates/shifts/shift_detail_printable.html:53 msgid "Excused" msgstr "Entschuldigt" -#: shifts/models.py:942 shifts/templates/shifts/shift_detail.html:352 +#: shifts/models.py:942 shifts/templates/shifts/shift_detail.html:357 msgid "Cancelled" msgstr "Abgesagt" #: shifts/models.py:943 shifts/templates/shifts/shift_day_printable.html:264 -#: shifts/templates/shifts/shift_detail.html:336 +#: shifts/templates/shifts/shift_detail.html:341 #: shifts/templates/shifts/shift_detail_printable.html:94 #: shifts/templates/shifts/shift_filters.html:83 msgid "Looking for a stand-in" @@ -4414,7 +4414,7 @@ msgid "Cancels the search for a stand-in. Use this if you want to attend the shi msgstr "Beendet die Suche nach Vertretung. Benutze dies, wenn du die Schicht wahrnehmen möchtest." #: shifts/templates/shifts/shift_detail.html:185 -#: shifts/templates/shifts/shift_detail.html:325 +#: shifts/templates/shifts/shift_detail.html:330 msgid "Cancel looking for a stand-in" msgstr "Beende die Suche nach Vertretung" @@ -4484,12 +4484,17 @@ msgstr "Melde mich ab" msgid "" "You can only register\n" " yourself\n" -" for a shift if:
\n" -" -You are not registered to another slot in that shift
\n" +" for a shift if:\n" +"
\n" +" -You are not registered to another slot in that shift\n" +"
\n" " -You have the required qualification (if you want to get a\n" -" qualification, contact the member office)
\n" -" -The shift is in the future
\n" -" -The shift is not cancelled (holidays...)
\n" +" qualification, contact the member office)\n" +"
\n" +" -The shift is in the future\n" +"
\n" +" -The shift is not cancelled (holidays...)\n" +"
\n" " " msgstr "" "Du kannst dich nur für eine Schicht anmelden, wenn\n" @@ -4498,12 +4503,12 @@ msgstr "" "- die Schicht in der Zukunft liegt\n" " " -#: shifts/templates/shifts/shift_detail.html:277 +#: shifts/templates/shifts/shift_detail.html:282 #: shifts/templates/shifts/shift_template_detail.html:104 msgid "Not specified" msgstr "" -#: shifts/templates/shifts/shift_detail.html:360 +#: shifts/templates/shifts/shift_detail.html:365 msgid "Edit slot" msgstr "Slot bearbeiten" From ced1e2dcd2e77c974fcef789f8cb44bf8c1001e5 Mon Sep 17 00:00:00 2001 From: crosspolar <18083323+crosspolar@users.noreply.github.com> Date: Fri, 10 Jul 2026 17:50:21 +0200 Subject: [PATCH 12/14] remove comment --- tapir/shifts/views/views.py | 1 - tapir/translations/locale/de/LC_MESSAGES/django.po | 14 +++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/tapir/shifts/views/views.py b/tapir/shifts/views/views.py index 8a4eb5d8a..d40c1788a 100644 --- a/tapir/shifts/views/views.py +++ b/tapir/shifts/views/views.py @@ -334,7 +334,6 @@ def get_queryset(self): class ShiftTemplateEndDateView( LoginRequiredMixin, PermissionRequiredMixin, - # TapirFormMixin, generic.UpdateView, ): permission_required = PERMISSION_SHIFTS_MANAGE diff --git a/tapir/translations/locale/de/LC_MESSAGES/django.po b/tapir/translations/locale/de/LC_MESSAGES/django.po index 1376e0b6c..8fc2554fc 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-07-10 17:08+0200\n" +"POT-Creation-Date: 2026-07-10 17:50+0200\n" "PO-Revision-Date: 2025-07-07 13:06+0000\n" "Last-Translator: Weblate Admin \n" "Language-Team: German \n" @@ -3245,8 +3245,8 @@ msgstr "" msgid "I understand that this will delete the shift exemption and create a membership pause" msgstr "" -#: shifts/forms.py:746 shifts/forms.py:814 shifts/views/views.py:463 -#: shifts/views/views.py:464 +#: shifts/forms.py:746 shifts/forms.py:814 shifts/views/views.py:462 +#: shifts/views/views.py:463 msgid "Shift changes you would like to be informed about" msgstr "Schicht-Änderungen, bei denen du informiert werden möchtest" @@ -4746,7 +4746,7 @@ msgid "Recurring Shift Watches" msgstr "Wiederholende Schichtbeobachtungen" #: shifts/templates/shifts/shiftwatch_overview.html:25 -#: shifts/views/views.py:508 +#: shifts/views/views.py:507 msgid "Create a rule for recurring Shift Watches" msgstr "Erstelle eine Regel für sich wiederholende Schichtbeobachtungen" @@ -5195,17 +5195,17 @@ msgstr "Schichtkonto-Protokoll für: %(name)s" msgid "Create manual shift account entry for: %(link)s" msgstr "Erzeuge Schicht-Kontoeintrag für: %(link)s" -#: shifts/views/views.py:370 +#: shifts/views/views.py:369 #, fuzzy #| msgid "Shift attendance cancelled" msgid "Shift template was successfully cancelled" msgstr "Schicht" -#: shifts/views/views.py:446 +#: shifts/views/views.py:445 msgid "Frozen statuses updated." msgstr "" -#: shifts/views/views.py:511 +#: shifts/views/views.py:510 #, python-format msgid "Please select either %(shift_template_group)s and/or weekdays, or alternatively %(shift_templates)s." msgstr "" From 4e4083f50fd6b5da69a326547c4274a825ec4adb Mon Sep 17 00:00:00 2001 From: crosspolar <18083323+crosspolar@users.noreply.github.com> Date: Fri, 10 Jul 2026 18:10:33 +0200 Subject: [PATCH 13/14] remove cancel button --- .../shifts/shift_template_set_end_date.html | 14 +++++++------- tapir/translations/locale/de/LC_MESSAGES/django.po | 5 ++--- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/tapir/shifts/templates/shifts/shift_template_set_end_date.html b/tapir/shifts/templates/shifts/shift_template_set_end_date.html index 938bb683b..2d0e14072 100644 --- a/tapir/shifts/templates/shifts/shift_template_set_end_date.html +++ b/tapir/shifts/templates/shifts/shift_template_set_end_date.html @@ -13,16 +13,16 @@
{% translate 'Set end date for' %}: {{ shift_template.ge
{% csrf_token %} {% bootstrap_form form %} -
diff --git a/tapir/translations/locale/de/LC_MESSAGES/django.po b/tapir/translations/locale/de/LC_MESSAGES/django.po index 8fc2554fc..506fa1219 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-07-10 17:50+0200\n" +"POT-Creation-Date: 2026-07-10 18:09+0200\n" "PO-Revision-Date: 2025-07-07 13:06+0000\n" "Last-Translator: Weblate Admin \n" "Language-Team: German \n" @@ -2089,7 +2089,6 @@ msgid "Submit" msgstr "Abschicken" #: coop/templates/coop/extra_share_request.html:92 -#: shifts/templates/shifts/shift_template_set_end_date.html:25 #: shifts/templates/shifts/user_shifts_overview_tag.html:177 msgid "Cancel" msgstr "Abmelden" @@ -4709,7 +4708,7 @@ msgstr "" msgid "All shifts generated from this ABCD-shift after the selected date will be cancelled. Registered members will be notified." msgstr "" -#: shifts/templates/shifts/shift_template_set_end_date.html:22 +#: shifts/templates/shifts/shift_template_set_end_date.html:23 #, fuzzy #| msgid "Set shift attendance to" msgid "Set end date and cancel shifts" From f1a62701b28300fee0cfe8706367ce34e9dc5f7c Mon Sep 17 00:00:00 2001 From: crosspolar <18083323+crosspolar@users.noreply.github.com> Date: Fri, 10 Jul 2026 18:26:03 +0200 Subject: [PATCH 14/14] acknowledge that start_date can be None --- tapir/shifts/forms.py | 1 + .../locale/de/LC_MESSAGES/django.po | 44 +++++++++---------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/tapir/shifts/forms.py b/tapir/shifts/forms.py index 1f604d6c7..9a52bf665 100644 --- a/tapir/shifts/forms.py +++ b/tapir/shifts/forms.py @@ -473,6 +473,7 @@ def __init__(self, shift_template=None, *args, **kwargs): def clean_end_date(self): if ( self.cleaned_data["end_date"] + and self.instance.start_date is not None and self.cleaned_data["end_date"] < self.instance.start_date ): raise ValidationError(_("The end date must be later than the start date.")) diff --git a/tapir/translations/locale/de/LC_MESSAGES/django.po b/tapir/translations/locale/de/LC_MESSAGES/django.po index 506fa1219..700b2cb7a 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-07-10 18:09+0200\n" +"POT-Creation-Date: 2026-07-10 18:22+0200\n" "PO-Revision-Date: 2025-07-07 13:06+0000\n" "Last-Translator: Weblate Admin \n" "Language-Team: German \n" @@ -652,7 +652,7 @@ msgstr "Wird normalerweise leer gelassen. Das Datum kann in der Zukunft liegen, msgid "Number of shares to create" msgstr "Anzahl zu erstellender Anteile" -#: coop/forms.py:67 shifts/forms.py:478 +#: coop/forms.py:67 shifts/forms.py:479 msgid "The end date must be later than the start date." msgstr "Das Enddatum muss später als das Start-Datum sein" @@ -2703,7 +2703,7 @@ msgstr "Hat Qualifikation" msgid "Does not have qualification" msgstr "Hat die Qualifikation nicht" -#: coop/views/shareowner.py:656 shifts/forms.py:809 +#: coop/views/shareowner.py:656 shifts/forms.py:810 msgid "ABCD Week" msgstr "ABCD-Woche" @@ -3190,86 +3190,86 @@ msgstr "Das ausgewählte Mitglied muss ein investierendes Mitglied sein." msgid "This member is registered to at least one ABCD shift. Please confirm the change of attendance mode with the checkbox below." msgstr "" -#: shifts/forms.py:462 shifts/forms.py:628 +#: shifts/forms.py:462 shifts/forms.py:629 msgid "Cancellation Reason" msgstr "Grund der Absage" -#: shifts/forms.py:517 +#: shifts/forms.py:518 msgid "I have read the warning about the cancelled attendances and confirm that the exemption should be created" msgstr "Ich habe die Warnung über die abgesagte Schicht-Anwesenheit gelesen und bestätige, dass die Befreiung erzeugt werden soll" -#: shifts/forms.py:524 +#: shifts/forms.py:525 msgid "I have read the warning about the cancelled ABCD attendances and confirm that the exemption should be created" msgstr "Ich habe die Warnung über die abgebrochene ABCD-Teilnahme gelesen und bestätige, dass die Befreiung erzeugt werden soll" -#: shifts/forms.py:582 +#: shifts/forms.py:583 #, python-format msgid "The user will be unregistered from the following ABCD shifts because the exemption is longer than %(number_of_cycles)s cycles: %(attendances_display)s " msgstr "Das Mitglied wird von den folgenden ABCD-Schichten abgemeldet, weil die Befreiung länger als %(number_of_cycles)s Schichtzyklen ist: %(attendances_display)s " -#: shifts/forms.py:603 +#: shifts/forms.py:604 msgid "This shift has been deleted. It is not possible to cancel it." msgstr "Diese Schicht wurde bereits gelöscht. Es ist nicht möglich diese abzusagen." -#: shifts/forms.py:614 shifts/templates/shifts/shift_detail.html:8 +#: shifts/forms.py:615 shifts/templates/shifts/shift_detail.html:8 #: shifts/templates/shifts/shift_detail.html:30 msgid "Shift" msgstr "Schicht" -#: shifts/forms.py:615 +#: shifts/forms.py:616 msgid "already cancelled" msgstr "bereits bgesagt" -#: shifts/forms.py:629 +#: shifts/forms.py:630 msgid "This reason will be applied to all cancelled shifts." msgstr "" -#: shifts/forms.py:657 +#: shifts/forms.py:658 msgid "I understand that updating this ABCD shift will update all the corresponding future shifts" msgstr "" -#: shifts/forms.py:676 +#: shifts/forms.py:677 msgid "ABCD-Week" msgstr "ABCD-Woche" -#: shifts/forms.py:680 +#: shifts/forms.py:681 msgid "Weekdays" msgstr "Wochentage" -#: shifts/forms.py:705 +#: shifts/forms.py:706 msgid "I understand that adding or editing a slot to this ABCD shift will affect all the corresponding future shifts" msgstr "" -#: shifts/forms.py:714 +#: shifts/forms.py:715 msgid "I understand that this will delete the shift exemption and create a membership pause" msgstr "" -#: shifts/forms.py:746 shifts/forms.py:814 shifts/views/views.py:462 +#: shifts/forms.py:747 shifts/forms.py:815 shifts/views/views.py:462 #: shifts/views/views.py:463 msgid "Shift changes you would like to be informed about" msgstr "Schicht-Änderungen, bei denen du informiert werden möchtest" -#: shifts/forms.py:753 +#: shifts/forms.py:754 msgid "Notify me when these capabilities become available or unavailable" msgstr "" -#: shifts/forms.py:757 +#: shifts/forms.py:758 msgid "Get notified when someone with specific skills registers or unregisters" msgstr "" -#: shifts/forms.py:803 shifts/templates/shifts/shift_template_detail.html:7 +#: shifts/forms.py:804 shifts/templates/shifts/shift_template_detail.html:7 #: shifts/templates/shifts/shift_template_detail.html:15 #: shifts/templates/shifts/user_shifts_overview_tag.html:31 #: shifts/templates/shifts/user_shifts_overview_tag.html:43 msgid "ABCD Shift" msgstr "ABCD-Schicht" -#: shifts/forms.py:820 +#: shifts/forms.py:821 #, python-format msgid "If weekdays or %(shift_template_group)s are selected, %(shift_templates)s may not be selected, and vice versa." msgstr "" -#: shifts/forms.py:824 +#: shifts/forms.py:825 #, python-format msgid "At least one of the fields (%(shift_templates)s, weekdays, or %(shift_template_group)s) must be selected." msgstr ""