diff --git a/tapir/coop/templates/coop/pdf/membership_confirmation_pdf.default.html b/tapir/coop/templates/coop/pdf/membership_confirmation_pdf.default.html index 06b668811..3573b7283 100644 --- a/tapir/coop/templates/coop/pdf/membership_confirmation_pdf.default.html +++ b/tapir/coop/templates/coop/pdf/membership_confirmation_pdf.default.html @@ -1,8 +1,8 @@ + {% load static %} {% load django_bootstrap5 %} {% load i18n %} {% load utils %} - diff --git a/tapir/coop/templates/coop/tags/user_coop_share_ownership_list_tag.html b/tapir/coop/templates/coop/tags/user_coop_share_ownership_list_tag.html index 7340e7a33..4bf5a2b96 100644 --- a/tapir/coop/templates/coop/tags/user_coop_share_ownership_list_tag.html +++ b/tapir/coop/templates/coop/tags/user_coop_share_ownership_list_tag.html @@ -12,6 +12,10 @@
+ + picture_as_pdf{% translate 'Summary' %} + file_present{% translate 'Membership confirmation' %} diff --git a/tapir/coop/templates/coop/user_profile_pdf.html b/tapir/coop/templates/coop/user_profile_pdf.html new file mode 100644 index 000000000..af20ee20f --- /dev/null +++ b/tapir/coop/templates/coop/user_profile_pdf.html @@ -0,0 +1,262 @@ + +{% load static %} +{% load django_bootstrap5 %} +{% load i18n %} +{% load utils %} +{% load coop %} +{% get_current_language as LANGUAGE_CODE %} + + + + + {% translate "Member Profile" %}: {% get_display_name_full shareowner %} + + + + +

{% translate "Member Profile" %}: {% get_display_name_full shareowner %}

+
+

{% translate "Personal Data" %}

+
+
{% translate "Name" %}
+
+ {{ shareowner.get_info.first_name }} {{ shareowner.get_info.last_name }} +
+
{% translate "Email" %}
+
+ {% if shareowner.get_info.email %} + {{ shareowner.get_info.email }} + {% else %} + - + {% endif %} +
+
{% translate "Phone number" %}
+
+ {% if shareowner.get_info.phone_number %} + {{ shareowner.get_info.phone_number }} + {% else %} + - + {% endif %} +
+
{% translate "Birthdate" %}
+
+ {{ shareowner.get_info.birthdate|date:"d.m.Y"|default:"-" }} +
+
{% translate "Address" %}
+
+ {{ shareowner.get_info.get_display_address|default:"-" }} +
+
{% translate "Status" %}
+
+ {% member_status_colored_text shareowner %} +
+
+
+
+

{% translate "Shares" %}

+ {% if shareowner.share_ownerships.all|length > 0 %} + + + + + + + + + + + {% for ownership in shareowner.share_ownerships.all %} + + + + + + + {% endfor %} + +
#{% translate "Starts at" %}{% translate "Ends at" %}{% translate "Status" %}
{{ ownership.id }}{{ ownership.start_date|date:"d.m.Y"|default:"-" }} + {% if ownership.end_date %} + {{ ownership.end_date|date:"d.m.Y" }} + {% else %} + - + {% endif %} + + {% if ownership.is_active %} + {% translate "Active" %} + {% else %} + {% translate "Sold or future" %} + {% endif %} +
+ {% else %} +
{% translate "No shares found." %}
+ {% endif %} +
+
+

{% translate "Payments" %}

+ {% if shareowner.credited_payments.all|length > 0 %} + + + + + + + + + + + {% for payment in shareowner.credited_payments.all %} + + + + + + + {% endfor %} + +
{% translate "ID" %}{% translate "Date" %}{% translate "Description" %}{% translate "Amount" %}
{{ payment.id }}{{ payment.payment_date|date:"d.m.Y"|default:"-" }}{{ payment.description|default:"-" }}{{ payment.amount|floatformat:2 }} €
+ {% else %} +
{% translate "No payments found." %}
+ {% endif %} +
+
+

{% translate "Shifts" %} ({% blocktranslate count years=SHIFT_RETENTION_YEARS %}last year{% plural %}max. last {{ years }} years{% endblocktranslate %})

+ {% if attendances %} + + + + + + + + + + {% for att in attendances %} + + + + + + {% endfor %} + +
{% translate "Date & Time" %}{% translate "Description" %}{% translate "Status" %}
+ {% if att.slot.shift.start_time %} + {{ att.slot.shift.start_time|date:"d.m.Y H:i" }} + {% else %} + - + {% endif %} + + {% if att.slot.shift %} + {{ att.slot.shift.title|default:att.slot.name|default:"(no description)" }} + {% else %} + {% translate "(Slot removed)" %} + {% endif %} + {{ att.get_state_display }}
+ {% else %} +
{% translate "No completed shifts found." %}
+ {% endif %} +
+
+

{% translate "Shift account history" %} ({% blocktranslate count years=SHIFT_RETENTION_YEARS %}last year{% plural %}max. last {{ years }} years{% endblocktranslate %})

+ {% if attendances %} + + + + + + + + + + + {% for entry_data in entries_data %} + + + + + + + {% endfor %} + +
{% translate 'Date' %}{% translate 'Value' %}{% translate 'Balance at date' %}{% translate 'Description' %}
{{ entry_data.entry.date|date:"d.m.Y H:i" }}{{ entry_data.entry.value }}{{ entry_data.balance_at_date }}{{ entry_data.entry.description }}
+ {% else %} +
{% translate "No completed shifts found." %}
+ {% endif %} +
+ + + diff --git a/tapir/coop/urls.py b/tapir/coop/urls.py index d554cc392..134127cb4 100644 --- a/tapir/coop/urls.py +++ b/tapir/coop/urls.py @@ -255,4 +255,9 @@ views.MemberSelfRegisterApiView.as_view(), name="member_self_register", ), + path( + "member//profile_pdf", + views.UserProfilePDFView.as_view(), + name="user_profile_pdf", + ), ] diff --git a/tapir/coop/views/shareowner.py b/tapir/coop/views/shareowner.py index a9e330546..078eaff29 100644 --- a/tapir/coop/views/shareowner.py +++ b/tapir/coop/views/shareowner.py @@ -4,6 +4,8 @@ import django_filters import django_tables2 +import weasyprint +from dateutil.relativedelta import relativedelta from django.conf import settings from django.contrib import messages from django.contrib.auth.decorators import login_required, permission_required @@ -18,7 +20,7 @@ HttpResponseRedirect, ) from django.shortcuts import get_object_or_404, redirect -from django.template import Context, Template +from django.template import Context, Template, loader from django.utils import timezone from django.utils.translation import gettext_lazy as _ from django.utils.translation import pgettext_lazy @@ -93,6 +95,7 @@ SHIFT_ATTENDANCE_MODE_CHOICES, SHIFT_USER_CAPABILITY_CHOICES, Shift, + ShiftAccountEntry, ShiftExemption, ShiftTemplateGroup, ) @@ -1105,3 +1108,65 @@ def get_context_data(self, **kwargs): def get_success_url(self): return self.get_share_owner().get_absolute_url() + + +class UserProfilePDFView( + LoginRequiredMixin, PermissionRequiredMixin, generic.DetailView +): + model = ShareOwner + permission_required = PERMISSION_ACCOUNTS_MANAGE + pk_url_kwarg = "pk" + template_name = "coop/user_profile_pdf.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + shareowner = self.object + + attendances = [] + if shareowner.pk and shareowner.user is not None: + cutoff_date = timezone.now() - relativedelta( + years=settings.SHIFT_RETENTION_YEARS + ) + + attendances = ( + shareowner.user.shift_attendances.select_related("slot", "slot__shift") + .filter(slot__shift__start_time__gte=cutoff_date) + .order_by("slot__shift__start_time") + ) + entries_data = [ + { + "entry": entry, + "balance_at_date": shareowner.user.shift_user_data.get_account_balance( + at_date=entry.date + ), + } + for entry in ShiftAccountEntry.objects.filter( + user=shareowner.user, date__gte=cutoff_date + ).order_by("-date") + ] + + context.update( + { + "attendances": attendances, + "SHIFT_RETENTION_YEARS": settings.SHIFT_RETENTION_YEARS, + "shareowner": shareowner, + "generated_at": timezone.now(), + "entries_data": entries_data, + } + ) + return context + + def render_to_response(self, context, **response_kwargs): + request = self.request + html_string = loader.render_to_string( + self.template_name, context, request=request + ) + html = weasyprint.HTML( + string=html_string, base_url=request.build_absolute_uri("/") + ) + pdf = html.write_pdf(pdf_variant="pdf/a-1b") + + response = HttpResponse(pdf, content_type="application/pdf") + filename = f"user-{self.object.pk}-profile.pdf" + response["Content-Disposition"] = f'inline; filename="{filename}"' + return response diff --git a/tapir/settings.py b/tapir/settings.py index f64afa8a1..e1600c046 100644 --- a/tapir/settings.py +++ b/tapir/settings.py @@ -438,3 +438,6 @@ ) SESSION_COOKIE_AGE = 86400 # one day + +# Duration of years, after which shifts are not relevant enough to be saved +SHIFT_RETENTION_YEARS = 8 diff --git a/tapir/translations/locale/de/LC_MESSAGES/django.po b/tapir/translations/locale/de/LC_MESSAGES/django.po index 0e17400fd..e47366732 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-15 18:56+0200\n" "PO-Revision-Date: 2025-07-07 13:06+0000\n" "Last-Translator: Weblate Admin \n" "Language-Team: German \n" @@ -73,6 +73,7 @@ msgstr "Pronomen" #: coop/templates/coop/draftuser_detail.html:71 #: coop/templates/coop/draftuser_detail.html:142 #: coop/templates/coop/shareowner_detail.html:51 +#: coop/templates/coop/user_profile_pdf.html:108 msgid "Phone number" msgstr "Telefonnummer" @@ -80,6 +81,7 @@ msgstr "Telefonnummer" #: coop/models.py:73 coop/models.py:448 #: coop/templates/coop/draftuser_detail.html:146 #: coop/templates/coop/shareowner_detail.html:55 +#: coop/templates/coop/user_profile_pdf.html:116 msgid "Birthdate" msgstr "Geburtsdatum" @@ -289,8 +291,8 @@ msgid "I agree that my membership card will be scanned at the checkout when I ma msgstr "Ich bin damit einverstanden, dass meine Mitgliedskarte beim Einkauf an der Kasse gescannt und somit mein Einkauf erfasst und gespeichert wird:" #: accounts/templates/accounts/purchase_tracking_card.html:30 -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:176 #: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:180 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:184 msgid "Yes,No" msgstr "Ja, Nein" @@ -316,6 +318,7 @@ msgstr "Mitglied" #: accounts/templates/accounts/user_detail.html:27 #: coop/templates/coop/shareowner_detail.html:17 +#: coop/templates/coop/user_profile_pdf.html:94 msgid "Personal Data" msgstr "Persönliche Daten" @@ -337,9 +340,9 @@ msgstr "Benutzername bearbeiten" #: coop/templates/coop/draftuser_detail.html:238 #: coop/templates/coop/membershipresignation_detail.html:107 #: coop/templates/coop/shareowner_detail.html:30 -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:22 -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:100 -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:121 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:26 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:104 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:125 #: core/templates/core/featureflag_list.html:30 #: shifts/templates/shifts/shift_detail.html:65 #: shifts/templates/shifts/shift_template_detail.html:29 @@ -355,7 +358,8 @@ msgstr "Name und Pronomen bearbeiten" #: accounts/templates/accounts/user_detail.html:59 #: coop/templates/coop/draftuser_detail.html:70 #: coop/templates/coop/draftuser_detail.html:130 -#: coop/templates/coop/shareowner_detail.html:43 coop/views/draftuser.py:260 +#: coop/templates/coop/shareowner_detail.html:43 +#: coop/templates/coop/user_profile_pdf.html:96 coop/views/draftuser.py:260 #: core/templates/core/email_list.html:38 #: core/templates/core/featureflag_list.html:18 #: financingcampaign/templates/financingcampaign/general.html:25 @@ -372,6 +376,7 @@ msgstr "Nutzer*innenname" #: coop/templates/coop/draftuser_detail.html:73 #: coop/templates/coop/draftuser_detail.html:138 #: coop/templates/coop/shareowner_detail.html:47 +#: coop/templates/coop/user_profile_pdf.html:100 msgid "Email" msgstr "E-Mail-Adresse" @@ -391,6 +396,7 @@ msgstr "Fehlend" #: coop/templates/coop/draftuser_detail.html:72 #: coop/templates/coop/draftuser_detail.html:156 #: coop/templates/coop/shareowner_detail.html:65 +#: coop/templates/coop/user_profile_pdf.html:120 msgid "Address" msgstr "Adresse" @@ -530,8 +536,8 @@ msgstr "Schickt mir eine Anleitung!" msgid "Enter a valid username. This value may contain only letters, numbers, and ./-/_ characters." msgstr "Der angegebene Name ist ungültig. Er darf nur Buchstaben, Zahlen und die Symbole ./-/_ enthalten." -#: accounts/views.py:129 accounts/views.py:134 coop/views/shareowner.py:285 -#: coop/views/shareowner.py:290 +#: accounts/views.py:129 accounts/views.py:134 coop/views/shareowner.py:288 +#: coop/views/shareowner.py:293 #, python-format msgid "Edit member: %(name)s" msgstr "Mitglied bearbeiten: %(name)s" @@ -783,8 +789,8 @@ msgstr "Ist investierendes Mitglied" #: coop/models.py:90 coop/models.py:476 #: coop/templates/coop/draftuser_detail.html:176 -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:48 -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:175 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:52 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:179 msgid "Ratenzahlung" msgstr "Ratenzahlung" @@ -813,8 +819,8 @@ msgid "Investing" msgstr "Investierend" #: coop/models.py:369 coop/templates/coop/draftuser_detail.html:171 -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:111 -#: coop/views/statistics.py:135 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:115 +#: coop/templates/coop/user_profile_pdf.html:156 coop/views/statistics.py:135 msgid "Active" msgstr "Aktiv" @@ -866,7 +872,7 @@ msgstr "Zahlendes Mitglied" msgid "Credited member" msgstr "Empfangendes Mitglied" -#: coop/models.py:585 +#: coop/models.py:585 coop/templates/coop/user_profile_pdf.html:178 msgid "Amount" msgstr "Betrag" @@ -958,7 +964,7 @@ msgstr "Löschen bestätigen" #: coop/templates/coop/confirm_delete_incoming_payment.html:31 #: coop/templates/coop/confirm_delete_share_ownership.html:24 -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:135 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:139 #: financingcampaign/templates/financingcampaign/confirm_delete.html:24 #: shifts/templates/shifts/shift_confirm_delete.html:30 msgid "Delete" @@ -1020,9 +1026,11 @@ msgid "List of similar members" msgstr "Liste ähnlicher Mitglieder" #: coop/templates/coop/draftuser_detail.html:69 -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:31 -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:98 -#: coop/views/shareowner.py:611 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:35 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:102 +#: coop/templates/coop/user_profile_pdf.html:124 +#: coop/templates/coop/user_profile_pdf.html:139 +#: coop/templates/coop/user_profile_pdf.html:204 coop/views/shareowner.py:614 #: shifts/templates/shifts/user_shifts_overview_tag.html:26 msgid "Status" msgstr "Status" @@ -1045,7 +1053,7 @@ msgid "Shares requested" msgstr "Angeforderte Anteile" #: coop/templates/coop/draftuser_detail.html:190 -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:53 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:57 #: shifts/models.py:45 msgid "Welcome Session" msgstr "Willkommenstreffen" @@ -2022,7 +2030,7 @@ msgstr "Dein Konto in Tapir, das Mitgliedersystem von %(coop_name)s" #: coop/templates/coop/extra_share_request.html:7 #: coop/templates/coop/extra_share_request.html:17 -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:84 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:88 msgid "Buy more shares" msgstr "Weitere Anteile zeichnen" @@ -2101,7 +2109,8 @@ msgid "General Tapir Accounts" msgstr "Allgemeine Tapir-Konten" #: coop/templates/coop/incoming_payment_list.html:10 -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:168 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:172 +#: coop/templates/coop/user_profile_pdf.html:170 msgid "Payments" msgstr "Zahlungen" @@ -2488,10 +2497,14 @@ msgstr "" " " #: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:17 +msgid "Summary" +msgstr "Zusammenfassung" + +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:21 msgid "Membership confirmation" msgstr "Mitgliedsbestätigung" -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:35 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:39 #, fuzzy, python-format #| msgid "" #| "\n" @@ -2506,7 +2519,7 @@ msgstr "" " Mitglied #%(coop_share_owner_id)s\n" " " -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:40 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:44 #, fuzzy, python-format #| msgid "" #| "\n" @@ -2521,7 +2534,7 @@ msgstr "" " Mitglied #%(coop_share_owner_id)s\n" " " -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:56 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:60 #: shifts/models.py:933 shifts/templates/shifts/shift_day_printable.html:214 #: shifts/templates/shifts/shift_day_printable.html:276 #: shifts/templates/shifts/shift_detail.html:304 @@ -2529,36 +2542,39 @@ msgstr "" msgid "Attended" msgstr "Teilgenommen" -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:58 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:62 #: shifts/models.py:932 msgid "Pending" msgstr "Ausstehend" -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:65 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:69 msgid "Mark Attended" msgstr "Als teilgenommen markieren" -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:74 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:78 msgid "Owned shares" msgstr "Anteile" -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:92 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:96 msgid "List of shares owned by this member" msgstr "Liste der Anteile die dieses Mitglied gehören" -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:96 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:100 +#: coop/templates/coop/user_profile_pdf.html:137 msgid "Starts at" msgstr "Anfangsdatum" -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:97 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:101 +#: coop/templates/coop/user_profile_pdf.html:138 msgid "Ends at" msgstr "Endet am" -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:113 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:117 +#: coop/templates/coop/user_profile_pdf.html:158 msgid "Sold or future" msgstr "" -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:138 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:142 msgid "" "\n" " Only use this to correct mistakes, i.e. if the share was\n" @@ -2572,22 +2588,106 @@ msgstr "" "Bitte nur verwenden, wenn ein tatsächlicher Fehler vorliegt, z.B. ein Anteil eingetragen wurde, der nie gekauft wurde. Wenn die Person ihren Anteil einfach an den Coop zurückverkauft hat, markiere den Anteil bitte als 'verkauft'.\n" " " -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:161 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:165 msgid "Add Shares" msgstr "Anteile hinzufügen" -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:179 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:183 msgid "Willing to gift a share" msgstr "Bereit Anteile zu schenken" -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:189 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:193 msgid "Send membership confirmation email" msgstr "Mitgliedsbestätigung per Mail senden" -#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:195 +#: coop/templates/coop/tags/user_coop_share_ownership_list_tag.html:199 msgid "User is not a cooperative member." msgstr "Benutzer*in ist kein Genossenschaftsmitglied." +#: coop/templates/coop/user_profile_pdf.html:12 +#: coop/templates/coop/user_profile_pdf.html:92 +msgid "Member Profile" +msgstr "Mitgliederprofil" + +#: coop/templates/coop/user_profile_pdf.html:131 +msgid "Shares" +msgstr "Anteile" + +#: coop/templates/coop/user_profile_pdf.html:166 +msgid "No shares found." +msgstr "Keine Anteile gefunden" + +#: coop/templates/coop/user_profile_pdf.html:175 +msgid "ID" +msgstr "" + +#: coop/templates/coop/user_profile_pdf.html:176 +#: coop/templates/coop/user_profile_pdf.html:239 +#: financingcampaign/templates/financingcampaign/general.html:111 +#: log/templates/log/log_entry_list_tag.html:23 +#: shifts/templates/shifts/user_shift_account_log.html:26 +#: statistics/templates/statistics/tags/credit_account_card.html:17 +#: statistics/templates/statistics/tags/purchase_statistics_card.html:18 +msgid "Date" +msgstr "Datum" + +#: coop/templates/coop/user_profile_pdf.html:177 +#: coop/templates/coop/user_profile_pdf.html:203 +#: coop/templates/coop/user_profile_pdf.html:242 +#: core/templates/core/email_list.html:39 shifts/models.py:502 +#: shifts/models.py:1071 shifts/templates/shifts/user_shift_account_log.html:29 +msgid "Description" +msgstr "Beschreibung" + +#: coop/templates/coop/user_profile_pdf.html:193 +msgid "No payments found." +msgstr "Keine Anteile gefunden" + +#: coop/templates/coop/user_profile_pdf.html:197 shifts/apps.py:36 +#: shifts/templates/shifts/user_shifts_overview_tag.html:8 +msgid "Shifts" +msgstr "Schichten" + +#: coop/templates/coop/user_profile_pdf.html:197 +#: coop/templates/coop/user_profile_pdf.html:234 +#, python-format +msgid "last year" +msgid_plural "max. last %(years)s years" +msgstr[0] "" +msgstr[1] "" + +#: coop/templates/coop/user_profile_pdf.html:202 +msgid "Date & Time" +msgstr "" + +#: coop/templates/coop/user_profile_pdf.html:221 +msgid "(Slot removed)" +msgstr "" + +#: coop/templates/coop/user_profile_pdf.html:230 +#: coop/templates/coop/user_profile_pdf.html:257 +msgid "No completed shifts found." +msgstr "Keine Schichten gefunden" + +#: coop/templates/coop/user_profile_pdf.html:234 +msgid "Shift account history" +msgstr "Schichtkonto-Protokoll für: " + +#: coop/templates/coop/user_profile_pdf.html:240 +#: financingcampaign/templates/financingcampaign/general.html:112 +#: shifts/templates/shifts/user_shift_account_log.html:27 +msgid "Value" +msgstr "Wert" + +#: coop/templates/coop/user_profile_pdf.html:241 +#: shifts/templates/shifts/user_shift_account_log.html:28 +msgid "Balance at date" +msgstr "" + +#: coop/templates/coop/user_profile_pdf.html:260 +msgid "Generated on" +msgstr "Erzeugt am" + #: coop/views/draftuser.py:89 coop/views/draftuser.py:94 #, python-format msgid "Edit applicant: %(name)s" @@ -2664,71 +2764,71 @@ msgstr "Auszahlungsende" msgid "Cancel membership of %(name)s" msgstr "Beende Mitgliedschaft von %(name)s" -#: coop/views/shareowner.py:146 coop/views/shareowner.py:151 +#: coop/views/shareowner.py:149 coop/views/shareowner.py:154 #, python-format msgid "Edit share: %(name)s" msgstr "Anteil bearbeiten: %(name)s" -#: coop/views/shareowner.py:171 coop/views/shareowner.py:176 +#: coop/views/shareowner.py:174 coop/views/shareowner.py:179 #, python-format msgid "Add shares to %(name)s" msgstr "Anteile zu %(name)s hinzufügen" -#: coop/views/shareowner.py:390 +#: coop/views/shareowner.py:393 msgid "Membership confirmation email sent." msgstr "Mitgliedsbestätigung per Mail gesendet." -#: coop/views/shareowner.py:612 shifts/templates/shifts/shift_filters.html:45 +#: coop/views/shareowner.py:615 shifts/templates/shifts/shift_filters.html:45 msgid "Any" msgstr "Alle" -#: coop/views/shareowner.py:617 +#: coop/views/shareowner.py:620 #: shifts/templates/shifts/user_shifts_overview_tag.html:79 msgid "Shift Status" msgstr "Schichtstatus" -#: coop/views/shareowner.py:625 +#: coop/views/shareowner.py:628 msgid "Is registered to an ABCD-slot that requires a qualification" msgstr "Ist für eine ABCD-Schicht eingetragen, die Qualifikation erfordert" -#: coop/views/shareowner.py:633 +#: coop/views/shareowner.py:636 msgid "Is registered to a slot that requires a qualification" msgstr "Ist für eine Schicht eingetragen, die Qualifikation erfordert" -#: coop/views/shareowner.py:641 +#: coop/views/shareowner.py:644 msgid "Has qualification" msgstr "Hat Qualifikation" -#: coop/views/shareowner.py:649 +#: coop/views/shareowner.py:652 msgid "Does not have qualification" msgstr "Hat die Qualifikation nicht" -#: coop/views/shareowner.py:656 shifts/forms.py:788 +#: coop/views/shareowner.py:659 shifts/forms.py:788 msgid "ABCD Week" msgstr "ABCD-Woche" -#: coop/views/shareowner.py:659 +#: coop/views/shareowner.py:662 msgid "Is fully paid" msgstr "Hat vollständig bezahlt" -#: coop/views/shareowner.py:662 +#: coop/views/shareowner.py:665 msgid "Name or member ID" msgstr "Name oder Mitgliedsnummer" -#: coop/views/shareowner.py:666 +#: coop/views/shareowner.py:669 msgid "Is currently exempted from shifts" msgstr "Ist derzeit von der Schichtarbeit befreit" -#: coop/views/shareowner.py:671 +#: coop/views/shareowner.py:674 msgid "Shift Name" msgstr "Schichtname" -#: coop/views/shareowner.py:987 +#: coop/views/shareowner.py:990 msgctxt "Willing to give a share" msgid "No" msgstr "Nein" -#: coop/views/shareowner.py:1092 +#: coop/views/shareowner.py:1095 msgid "Thank you for signing additional shares, we truly appreciate your contribution and commitment! You will receive an email confirmation soon." msgstr "Vielen Dank für das Zeichnen weiterer Anteile, wir freuen und bedanken uns! Du bekommst in Kürze eine Bestätigung per Email." @@ -2836,11 +2936,6 @@ 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 -msgid "Description" -msgstr "Beschreibung" - #: core/templates/core/email_list.html:40 msgid "Subject" msgstr "Betreff" @@ -2945,19 +3040,6 @@ msgstr "" msgid "The list of all datapoints" msgstr "" -#: financingcampaign/templates/financingcampaign/general.html:111 -#: log/templates/log/log_entry_list_tag.html:23 -#: shifts/templates/shifts/user_shift_account_log.html:26 -#: statistics/templates/statistics/tags/credit_account_card.html:17 -#: statistics/templates/statistics/tags/purchase_statistics_card.html:18 -msgid "Date" -msgstr "Datum" - -#: financingcampaign/templates/financingcampaign/general.html:112 -#: shifts/templates/shifts/user_shift_account_log.html:27 -msgid "Value" -msgstr "Wert" - #: financingcampaign/templates/financingcampaign/general.html:113 msgid "Linked source" msgstr "" @@ -3039,10 +3121,6 @@ msgstr "Notiz hinzufügen" msgid "Log Type" msgstr "" -#: shifts/apps.py:36 shifts/templates/shifts/user_shifts_overview_tag.html:8 -msgid "Shifts" -msgstr "Schichten" - #: shifts/apps.py:39 shifts/templates/shifts/shift_calendar_future.html:4 #: shifts/templates/shifts/shift_calendar_future.html:7 msgid "Shift calendar" @@ -4870,10 +4948,6 @@ msgstr "Füge per Hand einen Eintrag hinzu" msgid "List of changes to this members shift account " msgstr "" -#: shifts/templates/shifts/user_shift_account_log.html:28 -msgid "Balance at date" -msgstr "" - #: shifts/templates/shifts/user_shifts_overview_tag.html:20 msgid "Watched Shifts" msgstr "Beobachtete Schichten" @@ -6572,6 +6646,11 @@ msgstr "%(name)s ist kein Mitglied der Genossenschaft. Vielleicht haben sie dere msgid "%(name)s has not attended a welcome session yet. Make sure they plan to do it!" msgstr "%(name)s hat an dem Willkommenstreffen noch nicht teilgenommen. Stelle sicher, dass er*sie es entsprechend einplant!" +#, fuzzy +#~| msgid "Preferred Language" +#~ msgid "Language" +#~ msgstr "Bevorzugte Sprache" + #, fuzzy, python-format #~| msgid "" #~| "\n"