diff --git a/aleksis/apps/alsijil/data_checks.py b/aleksis/apps/alsijil/data_checks.py index e6691b76347eb9b6aecaff916e4bc68e592d6633..679de00ee61914f8b4962a38cda5ba47f42a7bec 100644 --- a/aleksis/apps/alsijil/data_checks.py +++ b/aleksis/apps/alsijil/data_checks.py @@ -11,8 +11,6 @@ from templated_email import send_templated_mail from aleksis.core.util.core_helpers import celery_optional, get_site_preferences -from aleksis.core.util.core_helpers import celery_optional - class SolveOption: name: str = "default" diff --git a/aleksis/apps/alsijil/forms.py b/aleksis/apps/alsijil/forms.py index 7b74944b11716f608edf15958f90f7c5aec4c7ca..6024b8581642073064c9c20e965f4ae5d9269638 100644 --- a/aleksis/apps/alsijil/forms.py +++ b/aleksis/apps/alsijil/forms.py @@ -2,15 +2,18 @@ from datetime import datetime from django import forms from django.core.exceptions import ValidationError -from django.db.models import Count +from django.db.models import Count, Q from django.utils.translation import gettext_lazy as _ +from django_global_request.middleware import get_request from django_select2.forms import Select2Widget +from guardian.shortcuts import get_objects_for_user from material import Fieldset, Layout, Row from aleksis.apps.chronos.managers import TimetableType from aleksis.apps.chronos.models import TimePeriod from aleksis.core.models import Group, Person +from aleksis.core.util.predicates import check_global_permission from .models import ExcuseType, ExtraMark, LessonDocumentation, PersonalNote @@ -51,12 +54,7 @@ class SelectForm(forms.Form): queryset=None, label=_("Group"), required=False, widget=Select2Widget, ) teacher = forms.ModelChoiceField( - queryset=Person.objects.annotate( - lessons_count=Count("lessons_as_teacher") - ).filter(lessons_count__gt=0), - label=_("Teacher"), - required=False, - widget=Select2Widget, + queryset=None, label=_("Teacher"), required=False, widget=Select2Widget, ) def clean(self) -> dict: @@ -78,13 +76,41 @@ class SelectForm(forms.Form): return data def __init__(self, *args, **kwargs): + self.request = get_request() super().__init__(*args, **kwargs) - self.fields["group"].queryset = ( - Group.objects.for_current_school_term_or_all() - .annotate(lessons_count=Count("lessons")) - .filter(lessons_count__gt=0) + + person = self.request.user.person + + group_qs = Group.get_groups_with_lessons() + + # Filter selectable groups by permissions + if not check_global_permission(self.request.user, "alsijil.view_week"): + # 1) All groups the user is allowed to see the week view by object permissions + # 2) All groups the user is a member of an owner of + group_qs = ( + group_qs.filter( + pk__in=get_objects_for_user( + self.request.user, "core.view_week_class_register_group", Group + ).values_list("pk", flat=True) + ) + ).union(group_qs.filter(Q(members=person) | Q(owners=person))) + + # Flatten query by filtering groups by pk + self.fields["group"].queryset = Group.objects.filter( + pk__in=list(group_qs.values_list("pk", flat=True)) ) + teacher_qs = Person.objects.annotate( + lessons_count=Count("lessons_as_teacher") + ).filter(lessons_count__gt=0) + + # Filter selectable teachers by permissions + if not check_global_permission(self.request.user, "alsijil.view_week"): + # If the user hasn't the global permission, the user is only allowed to see his own person + teacher_qs = teacher_qs.filter(pk=person.pk) + + self.fields["teacher"].queryset = teacher_qs + PersonalNoteFormSet = forms.modelformset_factory( PersonalNote, form=PersonalNoteForm, max_num=0, extra=0 @@ -93,7 +119,6 @@ PersonalNoteFormSet = forms.modelformset_factory( class RegisterAbsenceForm(forms.Form): layout = Layout( - Fieldset("", "person"), Fieldset("", Row("date_start", "date_end"), Row("from_period", "to_period")), Fieldset("", Row("absent", "excused"), Row("excuse_type"), Row("remarks")), ) @@ -101,9 +126,6 @@ class RegisterAbsenceForm(forms.Form): date_end = forms.DateField(label=_("End date"), initial=datetime.today) from_period = forms.ChoiceField(label=_("Start period")) to_period = forms.ChoiceField(label=_("End period")) - person = forms.ModelChoiceField( - label=_("Person"), queryset=Person.objects.all(), widget=Select2Widget - ) absent = forms.BooleanField(label=_("Absent"), initial=True, required=False) excused = forms.BooleanField(label=_("Excused"), initial=True, required=False) excuse_type = forms.ModelChoiceField( @@ -115,6 +137,7 @@ class RegisterAbsenceForm(forms.Form): remarks = forms.CharField(label=_("Remarks"), max_length=30, required=False) def __init__(self, *args, **kwargs): + self.request = get_request() super().__init__(*args, **kwargs) period_choices = TimePeriod.period_choices diff --git a/aleksis/apps/alsijil/locale/ar/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/ar/LC_MESSAGES/django.po index 3e06d2db491f8a83e701d74ccf17bd342d47c2f5..faa115baa37ae9bda0f9670c89a95f268c5dd114 100644 --- a/aleksis/apps/alsijil/locale/ar/LC_MESSAGES/django.po +++ b/aleksis/apps/alsijil/locale/ar/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-11 11:08+0200\n" +"POT-Creation-Date: 2020-11-14 12:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -18,11 +18,12 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" -#: forms.py:26 +#: forms.py:29 msgid "Homework for the next lesson" msgstr "" -#: forms.py:51 templates/alsijil/print/full_register.html:199 +#: forms.py:54 templates/alsijil/class_register/week_view.html:168 +#: templates/alsijil/print/full_register.html:199 msgid "Group" msgstr "" @@ -31,57 +32,53 @@ msgstr "" msgid "Teacher" msgstr "" -#: forms.py:74 +#: forms.py:72 msgid "You can't select a group and a teacher both." msgstr "" -#: forms.py:100 +#: forms.py:125 msgid "Start date" msgstr "" -#: forms.py:101 +#: forms.py:126 msgid "End date" msgstr "" -#: forms.py:102 +#: forms.py:127 msgid "Start period" msgstr "" -#: forms.py:103 +#: forms.py:128 msgid "End period" msgstr "" -#: forms.py:105 templates/alsijil/class_register/lesson.html:163 -msgid "Person" -msgstr "" - -#: forms.py:107 templates/alsijil/class_register/lesson.html:164 -#: templates/alsijil/class_register/person.html:172 -#: templates/alsijil/class_register/week_view.html:119 +#: forms.py:129 templates/alsijil/class_register/lesson.html:243 +#: templates/alsijil/class_register/person.html:207 +#: templates/alsijil/class_register/week_view.html:261 #: templates/alsijil/print/full_register.html:75 #: templates/alsijil/print/full_register.html:312 msgid "Absent" msgstr "" -#: forms.py:108 templates/alsijil/class_register/lesson.html:166 -#: templates/alsijil/class_register/person.html:74 -#: templates/alsijil/class_register/person.html:180 +#: forms.py:130 templates/alsijil/class_register/lesson.html:245 +#: templates/alsijil/class_register/person.html:98 +#: templates/alsijil/class_register/person.html:215 #: templates/alsijil/partials/mark_as_buttons.html:2 #: templates/alsijil/partials/mark_as_buttons.html:3 +#: templates/alsijil/partials/persons_with_stats.html:74 #: templates/alsijil/print/full_register.html:84 #: templates/alsijil/print/full_register.html:275 msgid "Excused" msgstr "" -#: forms.py:110 models.py:38 models.py:69 -#: templates/alsijil/class_register/lesson.html:167 -#: templates/alsijil/class_register/lesson.html:202 +#: forms.py:132 models.py:41 models.py:74 +#: templates/alsijil/class_register/lesson.html:246 +#: templates/alsijil/class_register/lesson.html:281 msgid "Excuse type" msgstr "" -#: forms.py:115 templates/alsijil/class_register/lesson.html:170 -#: templates/alsijil/class_register/lesson.html:223 -#: templates/alsijil/class_register/lesson.html:231 +#: forms.py:137 templates/alsijil/class_register/lesson.html:248 +#: templates/alsijil/class_register/lesson.html:302 #: templates/alsijil/print/full_register.html:314 msgid "Remarks" msgstr "" @@ -94,107 +91,173 @@ msgstr "" msgid "Current lesson" msgstr "" -#: menus.py:22 +#: menus.py:27 msgid "Current week" msgstr "" -#: menus.py:28 templates/alsijil/class_register/groups.html:5 -#: templates/alsijil/class_register/groups.html:9 +#: menus.py:38 templates/alsijil/class_register/groups.html:5 +#: templates/alsijil/class_register/groups.html:8 msgid "My groups" msgstr "" -#: menus.py:34 +#: menus.py:49 msgid "My overview" msgstr "" -#: menus.py:40 templates/alsijil/class_register/persons.html:7 -#: templates/alsijil/class_register/persons.html:11 +#: menus.py:60 templates/alsijil/class_register/persons.html:5 +#: templates/alsijil/class_register/persons.html:9 msgid "My students" msgstr "" -#: menus.py:46 templates/alsijil/absences/register.html:5 -#: templates/alsijil/absences/register.html:6 -msgid "Register absence" -msgstr "" - -#: menus.py:52 models.py:39 templates/alsijil/excuse_type/list.html:8 +#: menus.py:71 models.py:42 templates/alsijil/excuse_type/list.html:8 #: templates/alsijil/excuse_type/list.html:9 +#: templates/alsijil/partials/legend.html:26 msgid "Excuse types" msgstr "" -#: menus.py:58 models.py:75 models.py:210 -#: templates/alsijil/class_register/lesson.html:168 +#: menus.py:82 models.py:80 models.py:215 +#: templates/alsijil/class_register/lesson.html:247 #: templates/alsijil/extra_mark/list.html:8 #: templates/alsijil/extra_mark/list.html:9 +#: templates/alsijil/partials/legend.html:41 +#: templates/alsijil/partials/persons_with_stats.html:19 #: templates/alsijil/print/full_register.html:293 msgid "Extra marks" msgstr "" -#: models.py:25 models.py:196 +#: model_extensions.py:145 +msgid "Can view week overview of group class register" +msgstr "" + +#: model_extensions.py:149 +msgid "Can view lesson overview of group class register" +msgstr "" + +#: model_extensions.py:152 +msgid "Can view all personal notes of a group" +msgstr "" + +#: model_extensions.py:155 +msgid "Can edit all personal notes of a group" +msgstr "" + +#: model_extensions.py:158 +msgid "Can view all lesson documentation of a group" +msgstr "" + +#: model_extensions.py:161 +msgid "Can edit all lesson documentation of a group" +msgstr "" + +#: model_extensions.py:163 +msgid "Can view full register of a group" +msgstr "" + +#: model_extensions.py:165 +msgid "Can register an absence for all members of a group" +msgstr "" + +#: model_extensions.py:168 +msgid "Can register an absence for a person" +msgstr "" + +#: models.py:28 models.py:201 msgid "Short name" msgstr "" -#: models.py:27 models.py:198 +#: models.py:30 models.py:203 templates/alsijil/class_register/groups.html:20 +#: templates/alsijil/partials/persons_with_stats.html:14 +#: templates/alsijil/partials/persons_with_stats.html:24 msgid "Name" msgstr "" -#: models.py:55 models.py:126 +#: models.py:60 models.py:131 msgid "Year" msgstr "" -#: models.py:106 +#: models.py:111 msgid "Personal note" msgstr "" -#: models.py:107 templates/alsijil/class_register/lesson.html:64 -#: templates/alsijil/class_register/lesson.html:156 -#: templates/alsijil/class_register/week_view.html:112 +#: models.py:112 templates/alsijil/class_register/lesson.html:101 +#: templates/alsijil/class_register/lesson.html:233 +#: templates/alsijil/class_register/week_view.html:68 +#: templates/alsijil/class_register/week_view.html:242 msgid "Personal notes" msgstr "" -#: models.py:132 templates/alsijil/class_register/week_view.html:64 +#: models.py:137 templates/alsijil/class_register/lesson.html:129 +#: templates/alsijil/class_register/week_view.html:90 +#: templates/alsijil/class_register/week_view.html:177 #: templates/alsijil/print/full_register.html:371 msgid "Lesson topic" msgstr "" -#: models.py:133 templates/alsijil/print/full_register.html:372 +#: models.py:138 templates/alsijil/class_register/lesson.html:137 +#: templates/alsijil/class_register/week_view.html:91 +#: templates/alsijil/class_register/week_view.html:183 +#: templates/alsijil/class_register/week_view.html:216 +#: templates/alsijil/print/full_register.html:372 msgid "Homework" msgstr "" -#: models.py:135 +#: models.py:140 templates/alsijil/class_register/lesson.html:145 +#: templates/alsijil/class_register/week_view.html:92 +#: templates/alsijil/class_register/week_view.html:189 +#: templates/alsijil/class_register/week_view.html:222 msgid "Group note" msgstr "" -#: models.py:178 templates/alsijil/class_register/lesson.html:60 -#: templates/alsijil/class_register/lesson.html:143 +#: models.py:183 templates/alsijil/class_register/lesson.html:97 +#: templates/alsijil/class_register/lesson.html:120 msgid "Lesson documentation" msgstr "" -#: models.py:179 +#: models.py:184 templates/alsijil/class_register/week_view.html:67 msgid "Lesson documentations" msgstr "" -#: models.py:209 +#: models.py:214 msgid "Extra mark" msgstr "" +#: models.py:222 +msgid "Can view week overview" +msgstr "" + +#: models.py:223 +msgid "Can register absence" +msgstr "" + +#: models.py:224 +msgid "Can list all personal note filters" +msgstr "" + #: preferences.py:16 msgid "Block adding personal notes for cancelled lessons" msgstr "" -#: preferences.py:25 +#: preferences.py:24 +msgid "Allow users to view their own personal notes" +msgstr "" + +#: preferences.py:33 +msgid "Allow primary group owners to register future absences for students in their groups" +msgstr "" + +#: preferences.py:43 msgid "Carry over data from first lesson period to the following lesson periods in lessons over multiple periods" msgstr "" -#: preferences.py:28 +#: preferences.py:46 msgid "This will carry over data only if the data in the following periods are empty." msgstr "" -#: preferences.py:38 +#: preferences.py:56 msgid "Allow teachers to open lesson periods on the same day and not just at the beginning of the period" msgstr "" -#: preferences.py:41 +#: preferences.py:59 msgid "Lessons in the past are not affected by this setting, you can open them whenever you want." msgstr "" @@ -202,76 +265,160 @@ msgstr "" msgid "Edit" msgstr "" -#: tables.py:22 tables.py:42 +#: tables.py:22 tables.py:42 templates/alsijil/class_register/person.html:249 msgid "Delete" msgstr "" -#: templates/alsijil/class_register/groups.html:20 +#: templates/alsijil/absences/register.html:5 +#: templates/alsijil/absences/register.html:6 +#: templates/alsijil/class_register/person.html:30 +#: templates/alsijil/class_register/week_view.html:256 +#: templates/alsijil/partials/persons_with_stats.html:115 +msgid "Register absence" +msgstr "" + +#: templates/alsijil/absences/register.html:9 +#: templates/alsijil/class_register/lesson.html:242 +msgid "Person" +msgstr "" + +#: templates/alsijil/class_register/groups.html:21 +msgid "Students" +msgstr "" + +#: templates/alsijil/class_register/groups.html:35 +#: templates/alsijil/class_register/groups.html:69 +#: templates/alsijil/class_register/week_view.html:40 +#: templates/alsijil/class_register/week_view.html:51 +msgid "Students list" +msgstr "" + +#: templates/alsijil/class_register/groups.html:39 +#: templates/alsijil/class_register/groups.html:75 +#: templates/alsijil/class_register/persons.html:27 +#: templates/alsijil/class_register/persons.html:43 +#: templates/alsijil/class_register/students_list.html:16 +#: templates/alsijil/class_register/students_list.html:35 +#: templates/alsijil/class_register/week_view.html:6 +msgid "Week view" +msgstr "" + +#: templates/alsijil/class_register/groups.html:44 +#: templates/alsijil/class_register/groups.html:82 +#: templates/alsijil/class_register/persons.html:31 +#: templates/alsijil/class_register/persons.html:50 +#: templates/alsijil/class_register/students_list.html:20 +#: templates/alsijil/class_register/students_list.html:42 +#: templates/alsijil/class_register/week_view.html:44 +#: templates/alsijil/class_register/week_view.html:58 +msgid "Generate printout" +msgstr "" + +#: templates/alsijil/class_register/groups.html:52 +#: templates/alsijil/class_register/groups.html:88 msgid "No groups available." msgstr "" -#: templates/alsijil/class_register/lesson.html:6 +#: templates/alsijil/class_register/groups.html:64 +msgid "students" +msgstr "" + +#: templates/alsijil/class_register/lesson.html:5 msgid "Lesson" msgstr "" -#: templates/alsijil/class_register/lesson.html:14 -#: templates/alsijil/class_register/lesson.html:83 -#, python-format -msgid "%(period)s. period" +#: templates/alsijil/class_register/lesson.html:20 +msgid "Back to week view" +msgstr "" + +#: templates/alsijil/class_register/lesson.html:29 +msgid "My previous lesson" msgstr "" #: templates/alsijil/class_register/lesson.html:38 -msgid "Previous lesson" +msgid "My next lesson" msgstr "" #: templates/alsijil/class_register/lesson.html:46 -msgid "Next lesson" +#: templates/alsijil/class_register/lesson.html:167 +#, python-format +msgid "%(period)s. period" +msgstr "" + +#: templates/alsijil/class_register/lesson.html:77 +#: templates/alsijil/class_register/lesson.html:359 +#, python-format +msgid "" +"\n" +" Previous %(subject)s lesson\n" +" " +msgstr "" + +#: templates/alsijil/class_register/lesson.html:85 +#: templates/alsijil/class_register/lesson.html:367 +#, python-format +msgid "" +"\n" +" Next %(subject)s lesson\n" +" " +msgstr "" + +#: templates/alsijil/class_register/lesson.html:107 +msgid "Previous lesson" msgstr "" -#: templates/alsijil/class_register/lesson.html:68 -#: templates/alsijil/class_register/lesson.html:249 +#: templates/alsijil/class_register/lesson.html:111 +#: templates/alsijil/class_register/lesson.html:342 msgid "Change history" msgstr "" -#: templates/alsijil/class_register/lesson.html:82 +#: templates/alsijil/class_register/lesson.html:166 msgid "Overview: Previous lesson" msgstr "" -#: templates/alsijil/class_register/lesson.html:89 +#: templates/alsijil/class_register/lesson.html:173 msgid "Lesson topic of previous lesson:" msgstr "" -#: templates/alsijil/class_register/lesson.html:96 +#: templates/alsijil/class_register/lesson.html:180 msgid "Homework for this lesson:" msgstr "" -#: templates/alsijil/class_register/lesson.html:103 +#: templates/alsijil/class_register/lesson.html:187 msgid "Group notes for previous lesson:" msgstr "" -#: templates/alsijil/class_register/lesson.html:110 +#: templates/alsijil/class_register/lesson.html:194 msgid "Absent persons:" msgstr "" -#: templates/alsijil/class_register/lesson.html:117 +#: templates/alsijil/class_register/lesson.html:201 msgid "Late persons:" msgstr "" -#: templates/alsijil/class_register/lesson.html:165 -#: templates/alsijil/class_register/person.html:86 +#: templates/alsijil/class_register/lesson.html:244 +#: templates/alsijil/class_register/person.html:110 +#: templates/alsijil/partials/persons_with_stats.html:17 +#: templates/alsijil/partials/persons_with_stats.html:34 +#: templates/alsijil/partials/persons_with_stats.html:91 #: templates/alsijil/print/full_register.html:287 msgid "Tardiness" msgstr "" -#: templates/alsijil/class_register/lesson.html:188 +#: templates/alsijil/class_register/lesson.html:267 msgid "Tardiness (in m)" msgstr "" -#: templates/alsijil/class_register/person.html:7 +#: templates/alsijil/class_register/person.html:8 msgid "Class register: person" msgstr "" -#: templates/alsijil/class_register/person.html:11 +#: templates/alsijil/class_register/person.html:16 +#: templates/alsijil/class_register/students_list.html:10 +msgid "Back" +msgstr "" + +#: templates/alsijil/class_register/person.html:19 #, python-format msgid "" "\n" @@ -279,118 +426,131 @@ msgid "" " " msgstr "" -#: templates/alsijil/class_register/person.html:19 +#: templates/alsijil/class_register/person.html:36 +#: templates/alsijil/partials/legend.html:14 msgid "Unexcused absences" msgstr "" -#: templates/alsijil/class_register/person.html:27 -#: templates/alsijil/class_register/person.html:44 -#: templates/alsijil/class_register/person.html:160 -#: templates/alsijil/class_register/person.html:202 +#: templates/alsijil/class_register/person.html:46 +#: templates/alsijil/class_register/person.html:65 +#: templates/alsijil/class_register/person.html:190 +#: templates/alsijil/class_register/person.html:237 msgid "Mark as" msgstr "" -#: templates/alsijil/class_register/person.html:30 -#: templates/alsijil/class_register/person.html:47 -#: templates/alsijil/class_register/person.html:163 -#: templates/alsijil/class_register/person.html:205 +#: templates/alsijil/class_register/person.html:49 +#: templates/alsijil/class_register/person.html:68 +#: templates/alsijil/class_register/person.html:193 +#: templates/alsijil/class_register/person.html:199 +#: templates/alsijil/class_register/person.html:240 +#: templates/alsijil/class_register/person.html:246 msgid "Delete note" msgstr "" -#: templates/alsijil/class_register/person.html:55 -msgid "There are unexcused lessons." +#: templates/alsijil/class_register/person.html:78 +msgid "There are no unexcused lessons." msgstr "" -#: templates/alsijil/class_register/person.html:59 +#: templates/alsijil/class_register/person.html:83 msgid "Statistics on absences, tardiness and remarks" msgstr "" -#: templates/alsijil/class_register/person.html:68 +#: templates/alsijil/class_register/person.html:92 +#: templates/alsijil/partials/legend.html:10 +#: templates/alsijil/partials/persons_with_stats.html:16 +#: templates/alsijil/partials/persons_with_stats.html:26 +#: templates/alsijil/partials/persons_with_stats.html:69 #: templates/alsijil/print/full_register.html:269 msgid "Absences" msgstr "" -#: templates/alsijil/class_register/person.html:72 +#: templates/alsijil/class_register/person.html:96 #: templates/alsijil/print/full_register.html:274 msgid "thereof" msgstr "" -#: templates/alsijil/class_register/person.html:82 +#: templates/alsijil/class_register/person.html:106 +#: templates/alsijil/partials/persons_with_stats.html:86 #: templates/alsijil/print/full_register.html:81 #: templates/alsijil/print/full_register.html:283 msgid "Unexcused" msgstr "" -#: templates/alsijil/class_register/person.html:102 +#: templates/alsijil/class_register/person.html:127 #: templates/alsijil/print/full_register.html:304 msgid "Relevant personal notes" msgstr "" -#: templates/alsijil/class_register/person.html:118 +#: templates/alsijil/class_register/person.html:143 #, python-format msgid "Week %(week)s" msgstr "" -#: templates/alsijil/class_register/person.html:126 -#: templates/alsijil/class_register/person.html:135 +#: templates/alsijil/class_register/person.html:152 +#: templates/alsijil/class_register/person.html:163 msgid "Mark all as" msgstr "" -#: templates/alsijil/class_register/person.html:187 +#: templates/alsijil/class_register/person.html:222 #, python-format msgid "%(late)s' late" msgstr "" -#: templates/alsijil/class_register/persons.html:22 -msgid "No students available." -msgstr "" - -#: templates/alsijil/class_register/week_view.html:6 -msgid "Week view" +#: templates/alsijil/class_register/students_list.html:5 +#: templates/alsijil/class_register/students_list.html:12 +#, python-format +msgid "Students list: %(group)s" msgstr "" -#: templates/alsijil/class_register/week_view.html:30 +#: templates/alsijil/class_register/week_view.html:23 msgid "Select" msgstr "" -#: templates/alsijil/class_register/week_view.html:38 +#: templates/alsijil/class_register/week_view.html:31 #, python-format msgid "" "CW %(week)s:\n" " %(instance)s" msgstr "" -#: templates/alsijil/class_register/week_view.html:58 +#: templates/alsijil/class_register/week_view.html:84 msgid "Period" msgstr "" -#: templates/alsijil/class_register/week_view.html:60 +#: templates/alsijil/class_register/week_view.html:86 msgid "Groups" msgstr "" -#: templates/alsijil/class_register/week_view.html:62 +#: templates/alsijil/class_register/week_view.html:88 +#: templates/alsijil/class_register/week_view.html:163 #: templates/alsijil/print/full_register.html:169 #: templates/alsijil/print/full_register.html:200 msgid "Subject" msgstr "" -#: templates/alsijil/class_register/week_view.html:63 +#: templates/alsijil/class_register/week_view.html:89 +#: templates/alsijil/class_register/week_view.html:173 msgid "Teachers" msgstr "" -#: templates/alsijil/class_register/week_view.html:120 +#: templates/alsijil/class_register/week_view.html:262 msgid "unexcused" msgstr "" -#: templates/alsijil/class_register/week_view.html:123 +#: templates/alsijil/class_register/week_view.html:265 msgid "Summed up tardiness" msgstr "" -#: templates/alsijil/class_register/week_view.html:152 +#: templates/alsijil/class_register/week_view.html:268 +#: templates/alsijil/partials/persons_with_stats.html:94 +msgid "Count of tardiness" +msgstr "" + +#: templates/alsijil/class_register/week_view.html:297 msgid "No lessons available" msgstr "" -#: templates/alsijil/class_register/week_view.html:155 +#: templates/alsijil/class_register/week_view.html:300 msgid "" "\n" " There are no lessons for the selected group or teacher in this week.\n" @@ -399,7 +559,7 @@ msgstr "" #: templates/alsijil/excuse_type/create.html:6 #: templates/alsijil/excuse_type/create.html:7 -#: templates/alsijil/excuse_type/list.html:16 +#: templates/alsijil/excuse_type/list.html:18 msgid "Create excuse type" msgstr "" @@ -427,16 +587,33 @@ msgstr "" msgid "Edit extra mark" msgstr "" -#: templates/alsijil/partials/absences.html:4 +#: templates/alsijil/partials/absences.html:6 +#: templates/alsijil/partials/persons_with_stats.html:27 +#: templates/alsijil/partials/persons_with_stats.html:44 #: templates/alsijil/print/full_register.html:126 msgid "(e)" msgstr "" -#: templates/alsijil/partials/absences.html:4 +#: templates/alsijil/partials/absences.html:6 +#: templates/alsijil/partials/persons_with_stats.html:33 +#: templates/alsijil/partials/persons_with_stats.html:50 #: templates/alsijil/print/full_register.html:130 msgid "(u)" msgstr "" +#: templates/alsijil/partials/legend.html:4 +msgid "Legend" +msgstr "" + +#: templates/alsijil/partials/legend.html:7 +#: templates/alsijil/print/full_register.html:71 +msgid "General" +msgstr "" + +#: templates/alsijil/partials/legend.html:18 +msgid "Excused absences" +msgstr "" + #: templates/alsijil/partials/lesson_status_icon.html:6 msgid "Data complete" msgstr "" @@ -465,6 +642,27 @@ msgstr "" msgid "e" msgstr "" +#: templates/alsijil/partials/persons_with_stats.html:7 +msgid "No students available." +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:15 +#: templates/alsijil/partials/persons_with_stats.html:25 +msgid "Primary group" +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:43 +msgid "Sum" +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:107 +msgid "Show more details" +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:108 +msgid "Details" +msgstr "" + #: templates/alsijil/print/full_register.html:6 msgid "Class register:" msgstr "" @@ -512,10 +710,6 @@ msgstr "" msgid "Abbreviations" msgstr "" -#: templates/alsijil/print/full_register.html:71 -msgid "General" -msgstr "" - #: templates/alsijil/print/full_register.html:78 msgid "Late" msgstr "" @@ -630,62 +824,58 @@ msgstr "" msgid "Notes" msgstr "" -#: views.py:78 +#: views.py:69 msgid "You either selected an invalid lesson or there is currently no lesson in progress." msgstr "" -#: views.py:96 +#: views.py:95 msgid "You are not allowed to create a lesson documentation for a lesson in the future." msgstr "" -#: views.py:122 +#: views.py:133 msgid "The lesson documentation has been saved." msgstr "" -#: views.py:143 +#: views.py:156 msgid "The personal notes have been saved." msgstr "" -#: views.py:351 -msgid "There is no current school term." -msgstr "" - -#: views.py:532 +#: views.py:587 msgid "The absences have been marked as excused." msgstr "" -#: views.py:548 +#: views.py:605 msgid "The absence has been marked as excused." msgstr "" -#: views.py:653 +#: views.py:735 msgid "The absence has been saved." msgstr "" -#: views.py:670 +#: views.py:754 msgid "The personal note has been deleted." msgstr "" -#: views.py:691 +#: views.py:775 msgid "The extra mark has been created." msgstr "" -#: views.py:702 +#: views.py:786 msgid "The extra mark has been saved." msgstr "" -#: views.py:712 +#: views.py:796 msgid "The extra mark has been deleted." msgstr "" -#: views.py:732 +#: views.py:816 msgid "The excuse type has been created." msgstr "" -#: views.py:743 +#: views.py:827 msgid "The excuse type has been saved." msgstr "" -#: views.py:753 +#: views.py:837 msgid "The excuse type has been deleted." msgstr "" diff --git a/aleksis/apps/alsijil/locale/de_DE/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/de_DE/LC_MESSAGES/django.po index b0d96f7785d7b14aa5a338a6fe4b79648efb5890..740b4ab755bd4df7134065b87efff2aa57cbe748 100644 --- a/aleksis/apps/alsijil/locale/de_DE/LC_MESSAGES/django.po +++ b/aleksis/apps/alsijil/locale/de_DE/LC_MESSAGES/django.po @@ -7,10 +7,11 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-11 11:08+0200\n" -"PO-Revision-Date: 2020-09-06 17:48+0000\n" +"POT-Creation-Date: 2020-11-14 12:23+0100\n" +"PO-Revision-Date: 2020-11-14 11:29+0000\n" "Last-Translator: Jonathan Weth <teckids@jonathanweth.de>\n" -"Language-Team: German <https://translate.edugit.org/projects/aleksis/aleksis-app-alsijil/de/>\n" +"Language-Team: German <https://translate.edugit.org/projects/aleksis/" +"aleksis-app-alsijil/de/>\n" "Language: de_DE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,11 +19,12 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.1.1\n" -#: forms.py:26 +#: forms.py:29 msgid "Homework for the next lesson" msgstr "Hausaufgabe zur nächsten Stunde" -#: forms.py:51 templates/alsijil/print/full_register.html:199 +#: forms.py:54 templates/alsijil/class_register/week_view.html:168 +#: templates/alsijil/print/full_register.html:199 msgid "Group" msgstr "Gruppe" @@ -31,57 +33,53 @@ msgstr "Gruppe" msgid "Teacher" msgstr "Lehrkraft" -#: forms.py:74 +#: forms.py:72 msgid "You can't select a group and a teacher both." msgstr "Es kann nur entweder eine Gruppe oder eine Lehrkraft ausgewählt werden." -#: forms.py:100 +#: forms.py:125 msgid "Start date" msgstr "Startdatum" -#: forms.py:101 +#: forms.py:126 msgid "End date" msgstr "Enddatum" -#: forms.py:102 +#: forms.py:127 msgid "Start period" msgstr "Startstunde" -#: forms.py:103 +#: forms.py:128 msgid "End period" msgstr "Endstunde" -#: forms.py:105 templates/alsijil/class_register/lesson.html:163 -msgid "Person" -msgstr "Person" - -#: forms.py:107 templates/alsijil/class_register/lesson.html:164 -#: templates/alsijil/class_register/person.html:172 -#: templates/alsijil/class_register/week_view.html:119 +#: forms.py:129 templates/alsijil/class_register/lesson.html:243 +#: templates/alsijil/class_register/person.html:207 +#: templates/alsijil/class_register/week_view.html:261 #: templates/alsijil/print/full_register.html:75 #: templates/alsijil/print/full_register.html:312 msgid "Absent" msgstr "Abwesend" -#: forms.py:108 templates/alsijil/class_register/lesson.html:166 -#: templates/alsijil/class_register/person.html:74 -#: templates/alsijil/class_register/person.html:180 +#: forms.py:130 templates/alsijil/class_register/lesson.html:245 +#: templates/alsijil/class_register/person.html:98 +#: templates/alsijil/class_register/person.html:215 #: templates/alsijil/partials/mark_as_buttons.html:2 #: templates/alsijil/partials/mark_as_buttons.html:3 +#: templates/alsijil/partials/persons_with_stats.html:74 #: templates/alsijil/print/full_register.html:84 #: templates/alsijil/print/full_register.html:275 msgid "Excused" msgstr "Entschuldigt" -#: forms.py:110 models.py:38 models.py:69 -#: templates/alsijil/class_register/lesson.html:167 -#: templates/alsijil/class_register/lesson.html:202 +#: forms.py:132 models.py:41 models.py:74 +#: templates/alsijil/class_register/lesson.html:246 +#: templates/alsijil/class_register/lesson.html:281 msgid "Excuse type" msgstr "Entschuldigungsart" -#: forms.py:115 templates/alsijil/class_register/lesson.html:170 -#: templates/alsijil/class_register/lesson.html:223 -#: templates/alsijil/class_register/lesson.html:231 +#: forms.py:137 templates/alsijil/class_register/lesson.html:248 +#: templates/alsijil/class_register/lesson.html:302 #: templates/alsijil/print/full_register.html:314 msgid "Remarks" msgstr "Bemerkungen" @@ -94,109 +92,173 @@ msgstr "Klassenbuch" msgid "Current lesson" msgstr "Aktuelle Unterrichtsstunde" -#: menus.py:22 +#: menus.py:27 msgid "Current week" msgstr "Aktuelle Woche" -#: menus.py:28 templates/alsijil/class_register/groups.html:5 -#: templates/alsijil/class_register/groups.html:9 -#, fuzzy -#| msgid "Groups" +#: menus.py:38 templates/alsijil/class_register/groups.html:5 +#: templates/alsijil/class_register/groups.html:8 msgid "My groups" -msgstr "Gruppen" +msgstr "Meine Gruppen" -#: menus.py:34 +#: menus.py:49 msgid "My overview" msgstr "Meine Übersicht" -#: menus.py:40 templates/alsijil/class_register/persons.html:7 -#: templates/alsijil/class_register/persons.html:11 +#: menus.py:60 templates/alsijil/class_register/persons.html:5 +#: templates/alsijil/class_register/persons.html:9 msgid "My students" msgstr "Meine Schüler*innen" -#: menus.py:46 templates/alsijil/absences/register.html:5 -#: templates/alsijil/absences/register.html:6 -msgid "Register absence" -msgstr "Abwesenheit eintragen" - -#: menus.py:52 models.py:39 templates/alsijil/excuse_type/list.html:8 +#: menus.py:71 models.py:42 templates/alsijil/excuse_type/list.html:8 #: templates/alsijil/excuse_type/list.html:9 +#: templates/alsijil/partials/legend.html:26 msgid "Excuse types" msgstr "Entschuldigungsarten" -#: menus.py:58 models.py:75 models.py:210 -#: templates/alsijil/class_register/lesson.html:168 +#: menus.py:82 models.py:80 models.py:215 +#: templates/alsijil/class_register/lesson.html:247 #: templates/alsijil/extra_mark/list.html:8 #: templates/alsijil/extra_mark/list.html:9 +#: templates/alsijil/partials/legend.html:41 +#: templates/alsijil/partials/persons_with_stats.html:19 #: templates/alsijil/print/full_register.html:293 msgid "Extra marks" msgstr "Zusätzliche Markierungen" -#: models.py:25 models.py:196 +#: model_extensions.py:145 +msgid "Can view week overview of group class register" +msgstr "Kann Wochenübersicht des Gruppenklassenbuches sehen" + +#: model_extensions.py:149 +msgid "Can view lesson overview of group class register" +msgstr "Kann Stundenübersicht des Gruppenklassenbuches sehen" + +#: model_extensions.py:152 +msgid "Can view all personal notes of a group" +msgstr "Kann alle persönlichen Notizen einer Gruppe sehen" + +#: model_extensions.py:155 +msgid "Can edit all personal notes of a group" +msgstr "Kann alle persönlichen Notizen einer Gruppe bearbeiten" + +#: model_extensions.py:158 +msgid "Can view all lesson documentation of a group" +msgstr "Kann alle Unterrichtsdokumentationen für eine Gruppe sehen" + +#: model_extensions.py:161 +msgid "Can edit all lesson documentation of a group" +msgstr "Kann alle Unterrichtsdokumentationen für eine Gruppe bearbeiten" + +#: model_extensions.py:163 +msgid "Can view full register of a group" +msgstr "Kann komplettes Klassenbuch einer Gruppe sehen" + +#: model_extensions.py:165 +msgid "Can register an absence for all members of a group" +msgstr "Kann eine Absenz für alle Mitglieder eine Gruppe registrieren" + +#: model_extensions.py:168 +msgid "Can register an absence for a person" +msgstr "Kann eine Absenz für eine Person registrieren" + +#: models.py:28 models.py:201 msgid "Short name" msgstr "Kurzname" -#: models.py:27 models.py:198 +#: models.py:30 models.py:203 templates/alsijil/class_register/groups.html:20 +#: templates/alsijil/partials/persons_with_stats.html:14 +#: templates/alsijil/partials/persons_with_stats.html:24 msgid "Name" msgstr "Name" -#: models.py:55 models.py:126 +#: models.py:60 models.py:131 msgid "Year" msgstr "Jahr" -#: models.py:106 +#: models.py:111 msgid "Personal note" msgstr "Persönliche Notiz" -#: models.py:107 templates/alsijil/class_register/lesson.html:64 -#: templates/alsijil/class_register/lesson.html:156 -#: templates/alsijil/class_register/week_view.html:112 +#: models.py:112 templates/alsijil/class_register/lesson.html:101 +#: templates/alsijil/class_register/lesson.html:233 +#: templates/alsijil/class_register/week_view.html:68 +#: templates/alsijil/class_register/week_view.html:242 msgid "Personal notes" msgstr "Persönliche Notizen" -#: models.py:132 templates/alsijil/class_register/week_view.html:64 +#: models.py:137 templates/alsijil/class_register/lesson.html:129 +#: templates/alsijil/class_register/week_view.html:90 +#: templates/alsijil/class_register/week_view.html:177 #: templates/alsijil/print/full_register.html:371 msgid "Lesson topic" msgstr "Stundenthema" -#: models.py:133 templates/alsijil/print/full_register.html:372 +#: models.py:138 templates/alsijil/class_register/lesson.html:137 +#: templates/alsijil/class_register/week_view.html:91 +#: templates/alsijil/class_register/week_view.html:183 +#: templates/alsijil/class_register/week_view.html:216 +#: templates/alsijil/print/full_register.html:372 msgid "Homework" msgstr "Hausaufgaben" -#: models.py:135 +#: models.py:140 templates/alsijil/class_register/lesson.html:145 +#: templates/alsijil/class_register/week_view.html:92 +#: templates/alsijil/class_register/week_view.html:189 +#: templates/alsijil/class_register/week_view.html:222 msgid "Group note" msgstr "Gruppennotiz" -#: models.py:178 templates/alsijil/class_register/lesson.html:60 -#: templates/alsijil/class_register/lesson.html:143 +#: models.py:183 templates/alsijil/class_register/lesson.html:97 +#: templates/alsijil/class_register/lesson.html:120 msgid "Lesson documentation" msgstr "Stunden-Dokumentation" -#: models.py:179 +#: models.py:184 templates/alsijil/class_register/week_view.html:67 msgid "Lesson documentations" msgstr "Stunden-Dokumentationen" -#: models.py:209 +#: models.py:214 msgid "Extra mark" msgstr "Zusätzliche Markierung" +#: models.py:222 +msgid "Can view week overview" +msgstr "Kann die Wochenübersicht sehen" + +#: models.py:223 +msgid "Can register absence" +msgstr "Kann eine Absenz registrieren" + +#: models.py:224 +msgid "Can list all personal note filters" +msgstr "Kann alle Filter für persönliche Notizen anzeigen" + #: preferences.py:16 msgid "Block adding personal notes for cancelled lessons" msgstr "Blockiere das Hinzufügen von persönlichen Notizen für ausgefallene Stunden" -#: preferences.py:25 +#: preferences.py:24 +msgid "Allow users to view their own personal notes" +msgstr "Erlaube Nutzern, ihre eigenen persönlichen Notizen zu sehen" + +#: preferences.py:33 +msgid "Allow primary group owners to register future absences for students in their groups" +msgstr "Erlaube Primärgruppeninhabern Absenzen in der Zukunft für Mitglieder ihrer Gruppen zu registrieren" + +#: preferences.py:43 msgid "Carry over data from first lesson period to the following lesson periods in lessons over multiple periods" msgstr "Daten von der ersten Stunde zu weiteren folgenden Stunden übernehmen" -#: preferences.py:28 +#: preferences.py:46 msgid "This will carry over data only if the data in the following periods are empty." msgstr "Dies wird die Daten nur übernehmen, wenn die Daten in den Folgestunden leer sind." -#: preferences.py:38 +#: preferences.py:56 msgid "Allow teachers to open lesson periods on the same day and not just at the beginning of the period" msgstr "Erlaube Lehrkräften, Unterrichtsstunden bereits am gleichen Tag und nicht erst zu Beginn der Stunde zu öffnen" -#: preferences.py:41 +#: preferences.py:59 msgid "Lessons in the past are not affected by this setting, you can open them whenever you want." msgstr "Unterrichtsstunden in der Vergangenheit werden nicht durch diese Einstellung beeinflusst, sie können immer geöffnet werden." @@ -204,78 +266,166 @@ msgstr "Unterrichtsstunden in der Vergangenheit werden nicht durch diese Einstel msgid "Edit" msgstr "Bearbeiten" -#: tables.py:22 tables.py:42 +#: tables.py:22 tables.py:42 templates/alsijil/class_register/person.html:249 msgid "Delete" msgstr "Löschen" -#: templates/alsijil/class_register/groups.html:20 -#, fuzzy -#| msgid "No students available." +#: templates/alsijil/absences/register.html:5 +#: templates/alsijil/absences/register.html:6 +#: templates/alsijil/class_register/person.html:30 +#: templates/alsijil/class_register/week_view.html:256 +#: templates/alsijil/partials/persons_with_stats.html:115 +msgid "Register absence" +msgstr "Abwesenheit eintragen" + +#: templates/alsijil/absences/register.html:9 +#: templates/alsijil/class_register/lesson.html:242 +msgid "Person" +msgstr "Person" + +#: templates/alsijil/class_register/groups.html:21 +msgid "Students" +msgstr "Schüler*innen" + +#: templates/alsijil/class_register/groups.html:35 +#: templates/alsijil/class_register/groups.html:69 +#: templates/alsijil/class_register/week_view.html:40 +#: templates/alsijil/class_register/week_view.html:51 +msgid "Students list" +msgstr "Schüler*innenliste" + +#: templates/alsijil/class_register/groups.html:39 +#: templates/alsijil/class_register/groups.html:75 +#: templates/alsijil/class_register/persons.html:27 +#: templates/alsijil/class_register/persons.html:43 +#: templates/alsijil/class_register/students_list.html:16 +#: templates/alsijil/class_register/students_list.html:35 +#: templates/alsijil/class_register/week_view.html:6 +msgid "Week view" +msgstr "Wochenansicht" + +#: templates/alsijil/class_register/groups.html:44 +#: templates/alsijil/class_register/groups.html:82 +#: templates/alsijil/class_register/persons.html:31 +#: templates/alsijil/class_register/persons.html:50 +#: templates/alsijil/class_register/students_list.html:20 +#: templates/alsijil/class_register/students_list.html:42 +#: templates/alsijil/class_register/week_view.html:44 +#: templates/alsijil/class_register/week_view.html:58 +msgid "Generate printout" +msgstr "Ausdruck generieren" + +#: templates/alsijil/class_register/groups.html:52 +#: templates/alsijil/class_register/groups.html:88 msgid "No groups available." -msgstr "Keine Schüler*innen verfügbar." +msgstr "Keine Gruppen verfügbar." + +#: templates/alsijil/class_register/groups.html:64 +msgid "students" +msgstr "Schüler*innen" -#: templates/alsijil/class_register/lesson.html:6 +#: templates/alsijil/class_register/lesson.html:5 msgid "Lesson" msgstr "Unterrichtsstunde" -#: templates/alsijil/class_register/lesson.html:14 -#: templates/alsijil/class_register/lesson.html:83 +#: templates/alsijil/class_register/lesson.html:20 +msgid "Back to week view" +msgstr "Zurück zur Wochenübersicht" + +#: templates/alsijil/class_register/lesson.html:29 +msgid "My previous lesson" +msgstr "Meine vorherige Stunde" + +#: templates/alsijil/class_register/lesson.html:38 +msgid "My next lesson" +msgstr "Meine nächste Stunde" + +#: templates/alsijil/class_register/lesson.html:46 +#: templates/alsijil/class_register/lesson.html:167 #, python-format msgid "%(period)s. period" msgstr "%(period)s. Stunde" -#: templates/alsijil/class_register/lesson.html:38 +#: templates/alsijil/class_register/lesson.html:77 +#: templates/alsijil/class_register/lesson.html:359 +#, python-format +msgid "" +"\n" +" Previous %(subject)s lesson\n" +" " +msgstr "" +"\n" +" Vorherige %(subject)s Stunde\n" +" " + +#: templates/alsijil/class_register/lesson.html:85 +#: templates/alsijil/class_register/lesson.html:367 +#, python-format +msgid "" +"\n" +" Next %(subject)s lesson\n" +" " +msgstr "" +"\n" +" Nächste %(subject)s Stunde\n" +" " + +#: templates/alsijil/class_register/lesson.html:107 msgid "Previous lesson" msgstr "Vorherige Unterrichtsstunde" -#: templates/alsijil/class_register/lesson.html:46 -msgid "Next lesson" -msgstr "Nächste Unterrichtsstunde" - -#: templates/alsijil/class_register/lesson.html:68 -#: templates/alsijil/class_register/lesson.html:249 +#: templates/alsijil/class_register/lesson.html:111 +#: templates/alsijil/class_register/lesson.html:342 msgid "Change history" msgstr "Veränderungen" -#: templates/alsijil/class_register/lesson.html:82 +#: templates/alsijil/class_register/lesson.html:166 msgid "Overview: Previous lesson" msgstr "Übersicht: Vorherige Stunde" -#: templates/alsijil/class_register/lesson.html:89 +#: templates/alsijil/class_register/lesson.html:173 msgid "Lesson topic of previous lesson:" msgstr "Stundenthema der vorherigen Stunde:" -#: templates/alsijil/class_register/lesson.html:96 +#: templates/alsijil/class_register/lesson.html:180 msgid "Homework for this lesson:" msgstr "Hausaufgaben zu dieser Stunde:" -#: templates/alsijil/class_register/lesson.html:103 +#: templates/alsijil/class_register/lesson.html:187 msgid "Group notes for previous lesson:" msgstr "Gruppennotizen für die vorherige Stunde:" -#: templates/alsijil/class_register/lesson.html:110 +#: templates/alsijil/class_register/lesson.html:194 msgid "Absent persons:" msgstr "Abwesende Personen:" -#: templates/alsijil/class_register/lesson.html:117 +#: templates/alsijil/class_register/lesson.html:201 msgid "Late persons:" msgstr "Verspätete Personen:" -#: templates/alsijil/class_register/lesson.html:165 -#: templates/alsijil/class_register/person.html:86 +#: templates/alsijil/class_register/lesson.html:244 +#: templates/alsijil/class_register/person.html:110 +#: templates/alsijil/partials/persons_with_stats.html:17 +#: templates/alsijil/partials/persons_with_stats.html:34 +#: templates/alsijil/partials/persons_with_stats.html:91 #: templates/alsijil/print/full_register.html:287 msgid "Tardiness" msgstr "Verspätung" -#: templates/alsijil/class_register/lesson.html:188 +#: templates/alsijil/class_register/lesson.html:267 msgid "Tardiness (in m)" msgstr "Verspätung (in m)" -#: templates/alsijil/class_register/person.html:7 +#: templates/alsijil/class_register/person.html:8 msgid "Class register: person" msgstr "Klassenbuch: Person" -#: templates/alsijil/class_register/person.html:11 +#: templates/alsijil/class_register/person.html:16 +#: templates/alsijil/class_register/students_list.html:10 +msgid "Back" +msgstr "Zurück" + +#: templates/alsijil/class_register/person.html:19 #, python-format msgid "" "\n" @@ -286,120 +436,131 @@ msgstr "" " Klassenbuchübersicht für %(person)s\n" " " -#: templates/alsijil/class_register/person.html:19 +#: templates/alsijil/class_register/person.html:36 +#: templates/alsijil/partials/legend.html:14 msgid "Unexcused absences" msgstr "Unentschuldigte Fehlzeiten" -#: templates/alsijil/class_register/person.html:27 -#: templates/alsijil/class_register/person.html:44 -#: templates/alsijil/class_register/person.html:160 -#: templates/alsijil/class_register/person.html:202 +#: templates/alsijil/class_register/person.html:46 +#: templates/alsijil/class_register/person.html:65 +#: templates/alsijil/class_register/person.html:190 +#: templates/alsijil/class_register/person.html:237 msgid "Mark as" msgstr "Markiere als" -#: templates/alsijil/class_register/person.html:30 -#: templates/alsijil/class_register/person.html:47 -#: templates/alsijil/class_register/person.html:163 -#: templates/alsijil/class_register/person.html:205 -#, fuzzy -#| msgid "Delete filter" +#: templates/alsijil/class_register/person.html:49 +#: templates/alsijil/class_register/person.html:68 +#: templates/alsijil/class_register/person.html:193 +#: templates/alsijil/class_register/person.html:199 +#: templates/alsijil/class_register/person.html:240 +#: templates/alsijil/class_register/person.html:246 msgid "Delete note" -msgstr "Filter löschen" +msgstr "Notiz löschen" -#: templates/alsijil/class_register/person.html:55 -msgid "There are unexcused lessons." +#: templates/alsijil/class_register/person.html:78 +msgid "There are no unexcused lessons." msgstr "Es gibt keine unentschuldigten Unterrichtsstunden." -#: templates/alsijil/class_register/person.html:59 +#: templates/alsijil/class_register/person.html:83 msgid "Statistics on absences, tardiness and remarks" msgstr "Statistiken zu Fehlzeiten, Verspätungen und Bemerkungen" -#: templates/alsijil/class_register/person.html:68 +#: templates/alsijil/class_register/person.html:92 +#: templates/alsijil/partials/legend.html:10 +#: templates/alsijil/partials/persons_with_stats.html:16 +#: templates/alsijil/partials/persons_with_stats.html:26 +#: templates/alsijil/partials/persons_with_stats.html:69 #: templates/alsijil/print/full_register.html:269 msgid "Absences" msgstr "Fehlstunden" -#: templates/alsijil/class_register/person.html:72 +#: templates/alsijil/class_register/person.html:96 #: templates/alsijil/print/full_register.html:274 msgid "thereof" msgstr "davon" -#: templates/alsijil/class_register/person.html:82 +#: templates/alsijil/class_register/person.html:106 +#: templates/alsijil/partials/persons_with_stats.html:86 #: templates/alsijil/print/full_register.html:81 #: templates/alsijil/print/full_register.html:283 msgid "Unexcused" msgstr "Unentschuldigt" -#: templates/alsijil/class_register/person.html:102 +#: templates/alsijil/class_register/person.html:127 #: templates/alsijil/print/full_register.html:304 msgid "Relevant personal notes" msgstr "Relevante persönliche Notizen" -#: templates/alsijil/class_register/person.html:118 +#: templates/alsijil/class_register/person.html:143 #, python-format msgid "Week %(week)s" msgstr "Woche %(week)s" -#: templates/alsijil/class_register/person.html:126 -#: templates/alsijil/class_register/person.html:135 +#: templates/alsijil/class_register/person.html:152 +#: templates/alsijil/class_register/person.html:163 msgid "Mark all as" msgstr "Alle als markieren" -#: templates/alsijil/class_register/person.html:187 +#: templates/alsijil/class_register/person.html:222 #, python-format msgid "%(late)s' late" msgstr "%(late)s' verspätet" -#: templates/alsijil/class_register/persons.html:22 -msgid "No students available." -msgstr "Keine Schüler*innen verfügbar." - -#: templates/alsijil/class_register/week_view.html:6 -msgid "Week view" -msgstr "Wochenansicht" +#: templates/alsijil/class_register/students_list.html:5 +#: templates/alsijil/class_register/students_list.html:12 +#, python-format +msgid "Students list: %(group)s" +msgstr "Schüler*innenliste: %(group)s" -#: templates/alsijil/class_register/week_view.html:30 +#: templates/alsijil/class_register/week_view.html:23 msgid "Select" msgstr "Auswählen" -#: templates/alsijil/class_register/week_view.html:38 +#: templates/alsijil/class_register/week_view.html:31 #, python-format msgid "" "CW %(week)s:\n" " %(instance)s" msgstr "KW %(week)s: %(instance)s" -#: templates/alsijil/class_register/week_view.html:58 +#: templates/alsijil/class_register/week_view.html:84 msgid "Period" msgstr "Stunde" -#: templates/alsijil/class_register/week_view.html:60 +#: templates/alsijil/class_register/week_view.html:86 msgid "Groups" msgstr "Gruppen" -#: templates/alsijil/class_register/week_view.html:62 +#: templates/alsijil/class_register/week_view.html:88 +#: templates/alsijil/class_register/week_view.html:163 #: templates/alsijil/print/full_register.html:169 #: templates/alsijil/print/full_register.html:200 msgid "Subject" msgstr "Fach" -#: templates/alsijil/class_register/week_view.html:63 +#: templates/alsijil/class_register/week_view.html:89 +#: templates/alsijil/class_register/week_view.html:173 msgid "Teachers" msgstr "Lehrkräfte" -#: templates/alsijil/class_register/week_view.html:120 +#: templates/alsijil/class_register/week_view.html:262 msgid "unexcused" msgstr "unentschuldigt" -#: templates/alsijil/class_register/week_view.html:123 +#: templates/alsijil/class_register/week_view.html:265 msgid "Summed up tardiness" msgstr "Summierte Verspätung" -#: templates/alsijil/class_register/week_view.html:152 +#: templates/alsijil/class_register/week_view.html:268 +#: templates/alsijil/partials/persons_with_stats.html:94 +msgid "Count of tardiness" +msgstr "Anzahl der Verspätungen" + +#: templates/alsijil/class_register/week_view.html:297 msgid "No lessons available" msgstr "Keine Stunden verfügbar" -#: templates/alsijil/class_register/week_view.html:155 +#: templates/alsijil/class_register/week_view.html:300 msgid "" "\n" " There are no lessons for the selected group or teacher in this week.\n" @@ -411,7 +572,7 @@ msgstr "" #: templates/alsijil/excuse_type/create.html:6 #: templates/alsijil/excuse_type/create.html:7 -#: templates/alsijil/excuse_type/list.html:16 +#: templates/alsijil/excuse_type/list.html:18 msgid "Create excuse type" msgstr "Entschuldigungsart erstellen" @@ -443,16 +604,33 @@ msgstr "Zusätzliche Markierung erstellen" msgid "Edit extra mark" msgstr "Zusätzliche Markierung bearbeiten" -#: templates/alsijil/partials/absences.html:4 +#: templates/alsijil/partials/absences.html:6 +#: templates/alsijil/partials/persons_with_stats.html:27 +#: templates/alsijil/partials/persons_with_stats.html:44 #: templates/alsijil/print/full_register.html:126 msgid "(e)" msgstr "(e)" -#: templates/alsijil/partials/absences.html:4 +#: templates/alsijil/partials/absences.html:6 +#: templates/alsijil/partials/persons_with_stats.html:33 +#: templates/alsijil/partials/persons_with_stats.html:50 #: templates/alsijil/print/full_register.html:130 msgid "(u)" msgstr "(u)" +#: templates/alsijil/partials/legend.html:4 +msgid "Legend" +msgstr "Legende" + +#: templates/alsijil/partials/legend.html:7 +#: templates/alsijil/print/full_register.html:71 +msgid "General" +msgstr "Allgemein" + +#: templates/alsijil/partials/legend.html:18 +msgid "Excused absences" +msgstr "Entschuldigte Fehlzeiten" + #: templates/alsijil/partials/lesson_status_icon.html:6 msgid "Data complete" msgstr "Daten vollständig" @@ -481,6 +659,27 @@ msgstr "Vertretung" msgid "e" msgstr "e" +#: templates/alsijil/partials/persons_with_stats.html:7 +msgid "No students available." +msgstr "Keine Schüler*innen verfügbar." + +#: templates/alsijil/partials/persons_with_stats.html:15 +#: templates/alsijil/partials/persons_with_stats.html:25 +msgid "Primary group" +msgstr "Primärgruppe" + +#: templates/alsijil/partials/persons_with_stats.html:43 +msgid "Sum" +msgstr "Summe" + +#: templates/alsijil/partials/persons_with_stats.html:107 +msgid "Show more details" +msgstr "Mehr Details anzeigen" + +#: templates/alsijil/partials/persons_with_stats.html:108 +msgid "Details" +msgstr "Details" + #: templates/alsijil/print/full_register.html:6 msgid "Class register:" msgstr "Klassenbuch:" @@ -541,17 +740,13 @@ msgstr "Schulleitung" msgid "Abbreviations" msgstr "Abkürzungen" -#: templates/alsijil/print/full_register.html:71 -msgid "General" -msgstr "Allgemein" - #: templates/alsijil/print/full_register.html:78 msgid "Late" msgstr "Verspätet" #: templates/alsijil/print/full_register.html:89 msgid "Custom excuse types" -msgstr "Benutzerdefinierte Entschuldigunsarten" +msgstr "Benutzerdefinierte Entschuldigungsarten" #: templates/alsijil/print/full_register.html:101 msgid "Available extra marks" @@ -659,70 +854,67 @@ msgstr "Unterrichtsdokumentation für Woche" msgid "Notes" msgstr "Notizen" -#: views.py:78 +#: views.py:69 msgid "You either selected an invalid lesson or there is currently no lesson in progress." msgstr "" "Sie haben eine ungültige Stunde ausgewählt oder es\n" " läuft momentan keine Stunde." -#: views.py:96 +#: views.py:95 msgid "You are not allowed to create a lesson documentation for a lesson in the future." msgstr "Ihnen ist es nicht erlaubt, eine Eintragung für eine Unterrichtsstunde in der Zukunft vorzunehmen." -#: views.py:122 +#: views.py:133 msgid "The lesson documentation has been saved." msgstr "Die Stunden-Dokumentation wurde gespeichert." -#: views.py:143 +#: views.py:156 msgid "The personal notes have been saved." msgstr "Die persönlichen Notizen wurden gespeichert." -#: views.py:351 -msgid "There is no current school term." -msgstr "Es gibt aktuell kein Schuljahr." - -#: views.py:532 +#: views.py:587 msgid "The absences have been marked as excused." msgstr "Die Fehlzeiten wurden als entschuldigt markiert." -#: views.py:548 +#: views.py:605 msgid "The absence has been marked as excused." msgstr "Die Fehlzeit wurde als entschuldigt markiert." -#: views.py:653 +#: views.py:735 msgid "The absence has been saved." msgstr "Die Abwesenheit wurde gespeichert." -#: views.py:670 -#, fuzzy -#| msgid "The personal notes have been saved." +#: views.py:754 msgid "The personal note has been deleted." -msgstr "Die persönlichen Notizen wurden gespeichert." +msgstr "Die persönliche Notiz wurde gelöscht." -#: views.py:691 +#: views.py:775 msgid "The extra mark has been created." msgstr "Die zusätzliche Markierung wurde erstellt." -#: views.py:702 +#: views.py:786 msgid "The extra mark has been saved." msgstr "Die zusätzliche Markierung wurde gespeichert." -#: views.py:712 +#: views.py:796 msgid "The extra mark has been deleted." msgstr "Die zusätzliche Markierung wurde gelöscht." -#: views.py:732 +#: views.py:816 msgid "The excuse type has been created." msgstr "Die Entschuldigungsart wurde erstellt." -#: views.py:743 +#: views.py:827 msgid "The excuse type has been saved." msgstr "Die Entschuldigunsart wurde gespeichert." -#: views.py:753 +#: views.py:837 msgid "The excuse type has been deleted." msgstr "Die Entschuldigungsart wurde gelöscht." +#~ msgid "There is no current school term." +#~ msgstr "Es gibt aktuell kein Schuljahr." + #~ msgid "Manage absence" #~ msgstr "Abwesenheiten verwalten" @@ -759,9 +951,6 @@ msgstr "Die Entschuldigungsart wurde gelöscht." #~ msgid "Room" #~ msgstr "Raum" -#~ msgid "List of all personal note filters" -#~ msgstr "Liste aller Filter für persönliche Notizen" - #~ msgid "Subs." #~ msgstr "Vertr." diff --git a/aleksis/apps/alsijil/locale/fr/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/fr/LC_MESSAGES/django.po index c22380a600c010febaa1b6f6cac52a86a11e97b1..bc689edf464de32e6f80ff2f8f3932b1964149b9 100644 --- a/aleksis/apps/alsijil/locale/fr/LC_MESSAGES/django.po +++ b/aleksis/apps/alsijil/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-11 11:08+0200\n" +"POT-Creation-Date: 2020-11-14 12:23+0100\n" "PO-Revision-Date: 2020-07-26 14:08+0000\n" "Last-Translator: Marlene Grundey <grundema@katharineum.de>\n" "Language-Team: French <https://translate.edugit.org/projects/aleksis/aleksis-app-alsijil/fr/>\n" @@ -18,11 +18,12 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.0.1\n" -#: forms.py:26 +#: forms.py:29 msgid "Homework for the next lesson" msgstr "" -#: forms.py:51 templates/alsijil/print/full_register.html:199 +#: forms.py:54 templates/alsijil/class_register/week_view.html:168 +#: templates/alsijil/print/full_register.html:199 msgid "Group" msgstr "Groupe" @@ -31,63 +32,59 @@ msgstr "Groupe" msgid "Teacher" msgstr "Profs" -#: forms.py:74 +#: forms.py:72 msgid "You can't select a group and a teacher both." msgstr "" -#: forms.py:100 +#: forms.py:125 msgid "Start date" msgstr "Date de début" -#: forms.py:101 +#: forms.py:126 msgid "End date" msgstr "Date de fin" -#: forms.py:102 +#: forms.py:127 #, fuzzy #| msgid "From period" msgid "Start period" msgstr "De la période" -#: forms.py:103 +#: forms.py:128 #, fuzzy #| msgid "From period" msgid "End period" msgstr "De la période" -#: forms.py:105 templates/alsijil/class_register/lesson.html:163 -msgid "Person" -msgstr "Personne" - -#: forms.py:107 templates/alsijil/class_register/lesson.html:164 -#: templates/alsijil/class_register/person.html:172 -#: templates/alsijil/class_register/week_view.html:119 +#: forms.py:129 templates/alsijil/class_register/lesson.html:243 +#: templates/alsijil/class_register/person.html:207 +#: templates/alsijil/class_register/week_view.html:261 #: templates/alsijil/print/full_register.html:75 #: templates/alsijil/print/full_register.html:312 msgid "Absent" msgstr "Absent(e)" -#: forms.py:108 templates/alsijil/class_register/lesson.html:166 -#: templates/alsijil/class_register/person.html:74 -#: templates/alsijil/class_register/person.html:180 +#: forms.py:130 templates/alsijil/class_register/lesson.html:245 +#: templates/alsijil/class_register/person.html:98 +#: templates/alsijil/class_register/person.html:215 #: templates/alsijil/partials/mark_as_buttons.html:2 #: templates/alsijil/partials/mark_as_buttons.html:3 +#: templates/alsijil/partials/persons_with_stats.html:74 #: templates/alsijil/print/full_register.html:84 #: templates/alsijil/print/full_register.html:275 msgid "Excused" msgstr "Excusé" -#: forms.py:110 models.py:38 models.py:69 -#: templates/alsijil/class_register/lesson.html:167 -#: templates/alsijil/class_register/lesson.html:202 +#: forms.py:132 models.py:41 models.py:74 +#: templates/alsijil/class_register/lesson.html:246 +#: templates/alsijil/class_register/lesson.html:281 #, fuzzy #| msgid "Excused" msgid "Excuse type" msgstr "Excusé" -#: forms.py:115 templates/alsijil/class_register/lesson.html:170 -#: templates/alsijil/class_register/lesson.html:223 -#: templates/alsijil/class_register/lesson.html:231 +#: forms.py:137 templates/alsijil/class_register/lesson.html:248 +#: templates/alsijil/class_register/lesson.html:302 #: templates/alsijil/print/full_register.html:314 msgid "Remarks" msgstr "Remarque" @@ -100,121 +97,201 @@ msgstr "Registre de la classe" msgid "Current lesson" msgstr "Lecon actuelle" -#: menus.py:22 +#: menus.py:27 msgid "Current week" msgstr "Semaine actuelle" -#: menus.py:28 templates/alsijil/class_register/groups.html:5 -#: templates/alsijil/class_register/groups.html:9 +#: menus.py:38 templates/alsijil/class_register/groups.html:5 +#: templates/alsijil/class_register/groups.html:8 #, fuzzy #| msgid "Group" msgid "My groups" msgstr "Groupe" -#: menus.py:34 +#: menus.py:49 #, fuzzy #| msgid "Personal overview" msgid "My overview" msgstr "Vue d'ensemble personnelle" -#: menus.py:40 templates/alsijil/class_register/persons.html:7 -#: templates/alsijil/class_register/persons.html:11 +#: menus.py:60 templates/alsijil/class_register/persons.html:5 +#: templates/alsijil/class_register/persons.html:9 msgid "My students" msgstr "" -#: menus.py:46 templates/alsijil/absences/register.html:5 -#: templates/alsijil/absences/register.html:6 -msgid "Register absence" -msgstr "Registre de Absence" - -#: menus.py:52 models.py:39 templates/alsijil/excuse_type/list.html:8 +#: menus.py:71 models.py:42 templates/alsijil/excuse_type/list.html:8 #: templates/alsijil/excuse_type/list.html:9 +#: templates/alsijil/partials/legend.html:26 #, fuzzy #| msgid "Excused" msgid "Excuse types" msgstr "Excusé" -#: menus.py:58 models.py:75 models.py:210 -#: templates/alsijil/class_register/lesson.html:168 +#: menus.py:82 models.py:80 models.py:215 +#: templates/alsijil/class_register/lesson.html:247 #: templates/alsijil/extra_mark/list.html:8 #: templates/alsijil/extra_mark/list.html:9 +#: templates/alsijil/partials/legend.html:41 +#: templates/alsijil/partials/persons_with_stats.html:19 #: templates/alsijil/print/full_register.html:293 msgid "Extra marks" msgstr "" -#: models.py:25 models.py:196 +#: model_extensions.py:145 +msgid "Can view week overview of group class register" +msgstr "" + +#: model_extensions.py:149 +msgid "Can view lesson overview of group class register" +msgstr "" + +#: model_extensions.py:152 +#, fuzzy +#| msgid "List of all personal note filters" +msgid "Can view all personal notes of a group" +msgstr "Liste de filtres de notes personnelles" + +#: model_extensions.py:155 +#, fuzzy +#| msgid "List of all personal note filters" +msgid "Can edit all personal notes of a group" +msgstr "Liste de filtres de notes personnelles" + +#: model_extensions.py:158 +#, fuzzy +#| msgid "Lesson documentation for calendar week" +msgid "Can view all lesson documentation of a group" +msgstr "Documentation de cours pour la semaine calendrier" + +#: model_extensions.py:161 +#, fuzzy +#| msgid "Lesson documentation for calendar week" +msgid "Can edit all lesson documentation of a group" +msgstr "Documentation de cours pour la semaine calendrier" + +#: model_extensions.py:163 +msgid "Can view full register of a group" +msgstr "" + +#: model_extensions.py:165 +msgid "Can register an absence for all members of a group" +msgstr "" + +#: model_extensions.py:168 +#, fuzzy +#| msgid "Class register" +msgid "Can register an absence for a person" +msgstr "Registre de la classe" + +#: models.py:28 models.py:201 #, fuzzy #| msgid "First name" msgid "Short name" msgstr "Prénom" -#: models.py:27 models.py:198 +#: models.py:30 models.py:203 templates/alsijil/class_register/groups.html:20 +#: templates/alsijil/partials/persons_with_stats.html:14 +#: templates/alsijil/partials/persons_with_stats.html:24 msgid "Name" msgstr "" -#: models.py:55 models.py:126 +#: models.py:60 models.py:131 msgid "Year" msgstr "" -#: models.py:106 +#: models.py:111 #, fuzzy #| msgid "Personal notes" msgid "Personal note" msgstr "Notes personnelles" -#: models.py:107 templates/alsijil/class_register/lesson.html:64 -#: templates/alsijil/class_register/lesson.html:156 -#: templates/alsijil/class_register/week_view.html:112 +#: models.py:112 templates/alsijil/class_register/lesson.html:101 +#: templates/alsijil/class_register/lesson.html:233 +#: templates/alsijil/class_register/week_view.html:68 +#: templates/alsijil/class_register/week_view.html:242 msgid "Personal notes" msgstr "Notes personnelles" -#: models.py:132 templates/alsijil/class_register/week_view.html:64 +#: models.py:137 templates/alsijil/class_register/lesson.html:129 +#: templates/alsijil/class_register/week_view.html:90 +#: templates/alsijil/class_register/week_view.html:177 #: templates/alsijil/print/full_register.html:371 msgid "Lesson topic" msgstr "Sujet de cours" -#: models.py:133 templates/alsijil/print/full_register.html:372 +#: models.py:138 templates/alsijil/class_register/lesson.html:137 +#: templates/alsijil/class_register/week_view.html:91 +#: templates/alsijil/class_register/week_view.html:183 +#: templates/alsijil/class_register/week_view.html:216 +#: templates/alsijil/print/full_register.html:372 msgid "Homework" msgstr "Devoirs" -#: models.py:135 +#: models.py:140 templates/alsijil/class_register/lesson.html:145 +#: templates/alsijil/class_register/week_view.html:92 +#: templates/alsijil/class_register/week_view.html:189 +#: templates/alsijil/class_register/week_view.html:222 #, fuzzy #| msgid "Group" msgid "Group note" msgstr "Groupe" -#: models.py:178 templates/alsijil/class_register/lesson.html:60 -#: templates/alsijil/class_register/lesson.html:143 +#: models.py:183 templates/alsijil/class_register/lesson.html:97 +#: templates/alsijil/class_register/lesson.html:120 msgid "Lesson documentation" msgstr "Documentation de cours" -#: models.py:179 +#: models.py:184 templates/alsijil/class_register/week_view.html:67 #, fuzzy #| msgid "Lesson documentation" msgid "Lesson documentations" msgstr "Documentation de cours" -#: models.py:209 +#: models.py:214 msgid "Extra mark" msgstr "" +#: models.py:222 +msgid "Can view week overview" +msgstr "" + +#: models.py:223 +#, fuzzy +#| msgid "Register absence" +msgid "Can register absence" +msgstr "Registre de Absence" + +#: models.py:224 +#, fuzzy +#| msgid "List of all personal note filters" +msgid "Can list all personal note filters" +msgstr "Liste de filtres de notes personnelles" + #: preferences.py:16 msgid "Block adding personal notes for cancelled lessons" msgstr "" -#: preferences.py:25 +#: preferences.py:24 +msgid "Allow users to view their own personal notes" +msgstr "" + +#: preferences.py:33 +msgid "Allow primary group owners to register future absences for students in their groups" +msgstr "" + +#: preferences.py:43 msgid "Carry over data from first lesson period to the following lesson periods in lessons over multiple periods" msgstr "" -#: preferences.py:28 +#: preferences.py:46 msgid "This will carry over data only if the data in the following periods are empty." msgstr "" -#: preferences.py:38 +#: preferences.py:56 msgid "Allow teachers to open lesson periods on the same day and not just at the beginning of the period" msgstr "" -#: preferences.py:41 +#: preferences.py:59 msgid "Lessons in the past are not affected by this setting, you can open them whenever you want." msgstr "" @@ -222,87 +299,175 @@ msgstr "" msgid "Edit" msgstr "" -#: tables.py:22 tables.py:42 +#: tables.py:22 tables.py:42 templates/alsijil/class_register/person.html:249 msgid "Delete" msgstr "" -#: templates/alsijil/class_register/groups.html:20 +#: templates/alsijil/absences/register.html:5 +#: templates/alsijil/absences/register.html:6 +#: templates/alsijil/class_register/person.html:30 +#: templates/alsijil/class_register/week_view.html:256 +#: templates/alsijil/partials/persons_with_stats.html:115 +msgid "Register absence" +msgstr "Registre de Absence" + +#: templates/alsijil/absences/register.html:9 +#: templates/alsijil/class_register/lesson.html:242 +msgid "Person" +msgstr "Personne" + +#: templates/alsijil/class_register/groups.html:21 +msgid "Students" +msgstr "" + +#: templates/alsijil/class_register/groups.html:35 +#: templates/alsijil/class_register/groups.html:69 +#: templates/alsijil/class_register/week_view.html:40 +#: templates/alsijil/class_register/week_view.html:51 +msgid "Students list" +msgstr "" + +#: templates/alsijil/class_register/groups.html:39 +#: templates/alsijil/class_register/groups.html:75 +#: templates/alsijil/class_register/persons.html:27 +#: templates/alsijil/class_register/persons.html:43 +#: templates/alsijil/class_register/students_list.html:16 +#: templates/alsijil/class_register/students_list.html:35 +#: templates/alsijil/class_register/week_view.html:6 +msgid "Week view" +msgstr "Vue de semaine" + +#: templates/alsijil/class_register/groups.html:44 +#: templates/alsijil/class_register/groups.html:82 +#: templates/alsijil/class_register/persons.html:31 +#: templates/alsijil/class_register/persons.html:50 +#: templates/alsijil/class_register/students_list.html:20 +#: templates/alsijil/class_register/students_list.html:42 +#: templates/alsijil/class_register/week_view.html:44 +#: templates/alsijil/class_register/week_view.html:58 +msgid "Generate printout" +msgstr "" + +#: templates/alsijil/class_register/groups.html:52 +#: templates/alsijil/class_register/groups.html:88 msgid "No groups available." msgstr "" -#: templates/alsijil/class_register/lesson.html:6 +#: templates/alsijil/class_register/groups.html:64 +msgid "students" +msgstr "" + +#: templates/alsijil/class_register/lesson.html:5 msgid "Lesson" msgstr "Cours" -#: templates/alsijil/class_register/lesson.html:14 -#: templates/alsijil/class_register/lesson.html:83 -#, fuzzy, python-format -#| msgid "From period" -msgid "%(period)s. period" -msgstr "De la période" +#: templates/alsijil/class_register/lesson.html:20 +#, fuzzy +#| msgid "Week view" +msgid "Back to week view" +msgstr "Vue de semaine" + +#: templates/alsijil/class_register/lesson.html:29 +#, fuzzy +#| msgid "Current lesson" +msgid "My previous lesson" +msgstr "Lecon actuelle" #: templates/alsijil/class_register/lesson.html:38 #, fuzzy #| msgid "Current lesson" -msgid "Previous lesson" +msgid "My next lesson" msgstr "Lecon actuelle" #: templates/alsijil/class_register/lesson.html:46 +#: templates/alsijil/class_register/lesson.html:167 +#, fuzzy, python-format +#| msgid "From period" +msgid "%(period)s. period" +msgstr "De la période" + +#: templates/alsijil/class_register/lesson.html:77 +#: templates/alsijil/class_register/lesson.html:359 +#, python-format +msgid "" +"\n" +" Previous %(subject)s lesson\n" +" " +msgstr "" + +#: templates/alsijil/class_register/lesson.html:85 +#: templates/alsijil/class_register/lesson.html:367 +#, python-format +msgid "" +"\n" +" Next %(subject)s lesson\n" +" " +msgstr "" + +#: templates/alsijil/class_register/lesson.html:107 #, fuzzy #| msgid "Current lesson" -msgid "Next lesson" +msgid "Previous lesson" msgstr "Lecon actuelle" -#: templates/alsijil/class_register/lesson.html:68 -#: templates/alsijil/class_register/lesson.html:249 +#: templates/alsijil/class_register/lesson.html:111 +#: templates/alsijil/class_register/lesson.html:342 msgid "Change history" msgstr "Changement d' histoire" -#: templates/alsijil/class_register/lesson.html:82 +#: templates/alsijil/class_register/lesson.html:166 msgid "Overview: Previous lesson" msgstr "" -#: templates/alsijil/class_register/lesson.html:89 +#: templates/alsijil/class_register/lesson.html:173 msgid "Lesson topic of previous lesson:" msgstr "" -#: templates/alsijil/class_register/lesson.html:96 +#: templates/alsijil/class_register/lesson.html:180 msgid "Homework for this lesson:" msgstr "" -#: templates/alsijil/class_register/lesson.html:103 +#: templates/alsijil/class_register/lesson.html:187 msgid "Group notes for previous lesson:" msgstr "" -#: templates/alsijil/class_register/lesson.html:110 +#: templates/alsijil/class_register/lesson.html:194 #, fuzzy #| msgid "Absences" msgid "Absent persons:" msgstr "Absences" -#: templates/alsijil/class_register/lesson.html:117 +#: templates/alsijil/class_register/lesson.html:201 msgid "Late persons:" msgstr "" -#: templates/alsijil/class_register/lesson.html:165 -#: templates/alsijil/class_register/person.html:86 +#: templates/alsijil/class_register/lesson.html:244 +#: templates/alsijil/class_register/person.html:110 +#: templates/alsijil/partials/persons_with_stats.html:17 +#: templates/alsijil/partials/persons_with_stats.html:34 +#: templates/alsijil/partials/persons_with_stats.html:91 #: templates/alsijil/print/full_register.html:287 msgid "Tardiness" msgstr "Retard" -#: templates/alsijil/class_register/lesson.html:188 +#: templates/alsijil/class_register/lesson.html:267 #, fuzzy #| msgid "Tardiness" msgid "Tardiness (in m)" msgstr "Retard" -#: templates/alsijil/class_register/person.html:7 +#: templates/alsijil/class_register/person.html:8 #, fuzzy #| msgid "Class register" msgid "Class register: person" msgstr "Registre de la classe" -#: templates/alsijil/class_register/person.html:11 +#: templates/alsijil/class_register/person.html:16 +#: templates/alsijil/class_register/students_list.html:10 +msgid "Back" +msgstr "" + +#: templates/alsijil/class_register/person.html:19 #, python-format msgid "" "\n" @@ -310,122 +475,137 @@ msgid "" " " msgstr "" -#: templates/alsijil/class_register/person.html:19 +#: templates/alsijil/class_register/person.html:36 +#: templates/alsijil/partials/legend.html:14 #, fuzzy #| msgid "Unexcused" msgid "Unexcused absences" msgstr "injustifié(e)" -#: templates/alsijil/class_register/person.html:27 -#: templates/alsijil/class_register/person.html:44 -#: templates/alsijil/class_register/person.html:160 -#: templates/alsijil/class_register/person.html:202 +#: templates/alsijil/class_register/person.html:46 +#: templates/alsijil/class_register/person.html:65 +#: templates/alsijil/class_register/person.html:190 +#: templates/alsijil/class_register/person.html:237 msgid "Mark as" msgstr "" -#: templates/alsijil/class_register/person.html:30 -#: templates/alsijil/class_register/person.html:47 -#: templates/alsijil/class_register/person.html:163 -#: templates/alsijil/class_register/person.html:205 +#: templates/alsijil/class_register/person.html:49 +#: templates/alsijil/class_register/person.html:68 +#: templates/alsijil/class_register/person.html:193 +#: templates/alsijil/class_register/person.html:199 +#: templates/alsijil/class_register/person.html:240 +#: templates/alsijil/class_register/person.html:246 msgid "Delete note" msgstr "" -#: templates/alsijil/class_register/person.html:55 -msgid "There are unexcused lessons." +#: templates/alsijil/class_register/person.html:78 +msgid "There are no unexcused lessons." msgstr "" -#: templates/alsijil/class_register/person.html:59 +#: templates/alsijil/class_register/person.html:83 msgid "Statistics on absences, tardiness and remarks" msgstr "" -#: templates/alsijil/class_register/person.html:68 +#: templates/alsijil/class_register/person.html:92 +#: templates/alsijil/partials/legend.html:10 +#: templates/alsijil/partials/persons_with_stats.html:16 +#: templates/alsijil/partials/persons_with_stats.html:26 +#: templates/alsijil/partials/persons_with_stats.html:69 #: templates/alsijil/print/full_register.html:269 msgid "Absences" msgstr "Absences" -#: templates/alsijil/class_register/person.html:72 +#: templates/alsijil/class_register/person.html:96 #: templates/alsijil/print/full_register.html:274 msgid "thereof" msgstr "" -#: templates/alsijil/class_register/person.html:82 +#: templates/alsijil/class_register/person.html:106 +#: templates/alsijil/partials/persons_with_stats.html:86 #: templates/alsijil/print/full_register.html:81 #: templates/alsijil/print/full_register.html:283 msgid "Unexcused" msgstr "injustifié(e)" -#: templates/alsijil/class_register/person.html:102 +#: templates/alsijil/class_register/person.html:127 #: templates/alsijil/print/full_register.html:304 msgid "Relevant personal notes" msgstr "Notes personnelles importantes" -#: templates/alsijil/class_register/person.html:118 +#: templates/alsijil/class_register/person.html:143 #, python-format msgid "Week %(week)s" msgstr "" -#: templates/alsijil/class_register/person.html:126 -#: templates/alsijil/class_register/person.html:135 +#: templates/alsijil/class_register/person.html:152 +#: templates/alsijil/class_register/person.html:163 msgid "Mark all as" msgstr "" -#: templates/alsijil/class_register/person.html:187 +#: templates/alsijil/class_register/person.html:222 #, python-format msgid "%(late)s' late" msgstr "" -#: templates/alsijil/class_register/persons.html:22 -msgid "No students available." +#: templates/alsijil/class_register/students_list.html:5 +#: templates/alsijil/class_register/students_list.html:12 +#, python-format +msgid "Students list: %(group)s" msgstr "" -#: templates/alsijil/class_register/week_view.html:6 -msgid "Week view" -msgstr "Vue de semaine" - -#: templates/alsijil/class_register/week_view.html:30 +#: templates/alsijil/class_register/week_view.html:23 msgid "Select" msgstr "Sélectionner" -#: templates/alsijil/class_register/week_view.html:38 +#: templates/alsijil/class_register/week_view.html:31 #, python-format msgid "" "CW %(week)s:\n" " %(instance)s" msgstr "" -#: templates/alsijil/class_register/week_view.html:58 +#: templates/alsijil/class_register/week_view.html:84 msgid "Period" msgstr "Période" -#: templates/alsijil/class_register/week_view.html:60 +#: templates/alsijil/class_register/week_view.html:86 #, fuzzy #| msgid "Group" msgid "Groups" msgstr "Groupe" -#: templates/alsijil/class_register/week_view.html:62 +#: templates/alsijil/class_register/week_view.html:88 +#: templates/alsijil/class_register/week_view.html:163 #: templates/alsijil/print/full_register.html:169 #: templates/alsijil/print/full_register.html:200 msgid "Subject" msgstr "Sujet" -#: templates/alsijil/class_register/week_view.html:63 +#: templates/alsijil/class_register/week_view.html:89 +#: templates/alsijil/class_register/week_view.html:173 msgid "Teachers" msgstr "Profs" -#: templates/alsijil/class_register/week_view.html:120 +#: templates/alsijil/class_register/week_view.html:262 msgid "unexcused" msgstr "Injustifié(e)" -#: templates/alsijil/class_register/week_view.html:123 +#: templates/alsijil/class_register/week_view.html:265 msgid "Summed up tardiness" msgstr "Résumé des retards" -#: templates/alsijil/class_register/week_view.html:152 +#: templates/alsijil/class_register/week_view.html:268 +#: templates/alsijil/partials/persons_with_stats.html:94 +#, fuzzy +#| msgid "Summed up tardiness" +msgid "Count of tardiness" +msgstr "Résumé des retards" + +#: templates/alsijil/class_register/week_view.html:297 msgid "No lessons available" msgstr "" -#: templates/alsijil/class_register/week_view.html:155 +#: templates/alsijil/class_register/week_view.html:300 #, fuzzy #| msgid "" #| "\n" @@ -442,7 +622,7 @@ msgstr "" #: templates/alsijil/excuse_type/create.html:6 #: templates/alsijil/excuse_type/create.html:7 -#: templates/alsijil/excuse_type/list.html:16 +#: templates/alsijil/excuse_type/list.html:18 msgid "Create excuse type" msgstr "" @@ -470,16 +650,35 @@ msgstr "" msgid "Edit extra mark" msgstr "" -#: templates/alsijil/partials/absences.html:4 +#: templates/alsijil/partials/absences.html:6 +#: templates/alsijil/partials/persons_with_stats.html:27 +#: templates/alsijil/partials/persons_with_stats.html:44 #: templates/alsijil/print/full_register.html:126 msgid "(e)" msgstr "" -#: templates/alsijil/partials/absences.html:4 +#: templates/alsijil/partials/absences.html:6 +#: templates/alsijil/partials/persons_with_stats.html:33 +#: templates/alsijil/partials/persons_with_stats.html:50 #: templates/alsijil/print/full_register.html:130 msgid "(u)" msgstr "" +#: templates/alsijil/partials/legend.html:4 +msgid "Legend" +msgstr "" + +#: templates/alsijil/partials/legend.html:7 +#: templates/alsijil/print/full_register.html:71 +msgid "General" +msgstr "" + +#: templates/alsijil/partials/legend.html:18 +#, fuzzy +#| msgid "Unexcused" +msgid "Excused absences" +msgstr "injustifié(e)" + #: templates/alsijil/partials/lesson_status_icon.html:6 msgid "Data complete" msgstr "" @@ -508,6 +707,29 @@ msgstr "" msgid "e" msgstr "e" +#: templates/alsijil/partials/persons_with_stats.html:7 +msgid "No students available." +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:15 +#: templates/alsijil/partials/persons_with_stats.html:25 +#, fuzzy +#| msgid "Group" +msgid "Primary group" +msgstr "Groupe" + +#: templates/alsijil/partials/persons_with_stats.html:43 +msgid "Sum" +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:107 +msgid "Show more details" +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:108 +msgid "Details" +msgstr "" + #: templates/alsijil/print/full_register.html:6 #, fuzzy #| msgid "Class register" @@ -557,10 +779,6 @@ msgstr "Prof principale" msgid "Abbreviations" msgstr "" -#: templates/alsijil/print/full_register.html:71 -msgid "General" -msgstr "" - #: templates/alsijil/print/full_register.html:78 msgid "Late" msgstr "" @@ -679,71 +897,67 @@ msgstr "Documentation de cours pour la semaine calendrier" msgid "Notes" msgstr "Notes" -#: views.py:78 +#: views.py:69 msgid "You either selected an invalid lesson or there is currently no lesson in progress." msgstr "" -#: views.py:96 +#: views.py:95 msgid "You are not allowed to create a lesson documentation for a lesson in the future." msgstr "" -#: views.py:122 +#: views.py:133 #, fuzzy #| msgid "Lesson documentation for calendar week" msgid "The lesson documentation has been saved." msgstr "Documentation de cours pour la semaine calendrier" -#: views.py:143 +#: views.py:156 msgid "The personal notes have been saved." msgstr "" -#: views.py:351 -msgid "There is no current school term." -msgstr "" - -#: views.py:532 +#: views.py:587 msgid "The absences have been marked as excused." msgstr "" -#: views.py:548 +#: views.py:605 msgid "The absence has been marked as excused." msgstr "" -#: views.py:653 +#: views.py:735 msgid "The absence has been saved." msgstr "" -#: views.py:670 +#: views.py:754 #, fuzzy #| msgid "Lesson documentation for calendar week" msgid "The personal note has been deleted." msgstr "Documentation de cours pour la semaine calendrier" -#: views.py:691 +#: views.py:775 #, fuzzy #| msgid "Lesson documentation for calendar week" msgid "The extra mark has been created." msgstr "Documentation de cours pour la semaine calendrier" -#: views.py:702 +#: views.py:786 #, fuzzy #| msgid "Lesson documentation for calendar week" msgid "The extra mark has been saved." msgstr "Documentation de cours pour la semaine calendrier" -#: views.py:712 +#: views.py:796 msgid "The extra mark has been deleted." msgstr "" -#: views.py:732 +#: views.py:816 msgid "The excuse type has been created." msgstr "" -#: views.py:743 +#: views.py:827 msgid "The excuse type has been saved." msgstr "" -#: views.py:753 +#: views.py:837 msgid "The excuse type has been deleted." msgstr "" @@ -781,6 +995,3 @@ msgstr "" #~ msgid "Room" #~ msgstr "Salle" - -#~ msgid "List of all personal note filters" -#~ msgstr "Liste de filtres de notes personnelles" diff --git a/aleksis/apps/alsijil/locale/la/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/la/LC_MESSAGES/django.po index 1af7f285f3def24ce0135bcd7f3e37c562d8bb46..9e7d29cdecf99e25af3f8af0420a8b06ce1b7e72 100644 --- a/aleksis/apps/alsijil/locale/la/LC_MESSAGES/django.po +++ b/aleksis/apps/alsijil/locale/la/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-11 11:08+0200\n" +"POT-Creation-Date: 2020-11-14 12:23+0100\n" "PO-Revision-Date: 2020-07-26 14:08+0000\n" "Last-Translator: Julian <leuckerj@gmail.com>\n" "Language-Team: Latin <https://translate.edugit.org/projects/aleksis/aleksis-app-alsijil/la/>\n" @@ -18,11 +18,12 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.0.1\n" -#: forms.py:26 +#: forms.py:29 msgid "Homework for the next lesson" msgstr "" -#: forms.py:51 templates/alsijil/print/full_register.html:199 +#: forms.py:54 templates/alsijil/class_register/week_view.html:168 +#: templates/alsijil/print/full_register.html:199 msgid "Group" msgstr "Grex" @@ -31,57 +32,53 @@ msgstr "Grex" msgid "Teacher" msgstr "" -#: forms.py:74 +#: forms.py:72 msgid "You can't select a group and a teacher both." msgstr "" -#: forms.py:100 +#: forms.py:125 msgid "Start date" msgstr "" -#: forms.py:101 +#: forms.py:126 msgid "End date" msgstr "" -#: forms.py:102 +#: forms.py:127 msgid "Start period" msgstr "" -#: forms.py:103 +#: forms.py:128 msgid "End period" msgstr "" -#: forms.py:105 templates/alsijil/class_register/lesson.html:163 -msgid "Person" -msgstr "Persona" - -#: forms.py:107 templates/alsijil/class_register/lesson.html:164 -#: templates/alsijil/class_register/person.html:172 -#: templates/alsijil/class_register/week_view.html:119 +#: forms.py:129 templates/alsijil/class_register/lesson.html:243 +#: templates/alsijil/class_register/person.html:207 +#: templates/alsijil/class_register/week_view.html:261 #: templates/alsijil/print/full_register.html:75 #: templates/alsijil/print/full_register.html:312 msgid "Absent" msgstr "" -#: forms.py:108 templates/alsijil/class_register/lesson.html:166 -#: templates/alsijil/class_register/person.html:74 -#: templates/alsijil/class_register/person.html:180 +#: forms.py:130 templates/alsijil/class_register/lesson.html:245 +#: templates/alsijil/class_register/person.html:98 +#: templates/alsijil/class_register/person.html:215 #: templates/alsijil/partials/mark_as_buttons.html:2 #: templates/alsijil/partials/mark_as_buttons.html:3 +#: templates/alsijil/partials/persons_with_stats.html:74 #: templates/alsijil/print/full_register.html:84 #: templates/alsijil/print/full_register.html:275 msgid "Excused" msgstr "" -#: forms.py:110 models.py:38 models.py:69 -#: templates/alsijil/class_register/lesson.html:167 -#: templates/alsijil/class_register/lesson.html:202 +#: forms.py:132 models.py:41 models.py:74 +#: templates/alsijil/class_register/lesson.html:246 +#: templates/alsijil/class_register/lesson.html:281 msgid "Excuse type" msgstr "" -#: forms.py:115 templates/alsijil/class_register/lesson.html:170 -#: templates/alsijil/class_register/lesson.html:223 -#: templates/alsijil/class_register/lesson.html:231 +#: forms.py:137 templates/alsijil/class_register/lesson.html:248 +#: templates/alsijil/class_register/lesson.html:302 #: templates/alsijil/print/full_register.html:314 msgid "Remarks" msgstr "" @@ -94,115 +91,181 @@ msgstr "" msgid "Current lesson" msgstr "" -#: menus.py:22 +#: menus.py:27 msgid "Current week" msgstr "" -#: menus.py:28 templates/alsijil/class_register/groups.html:5 -#: templates/alsijil/class_register/groups.html:9 +#: menus.py:38 templates/alsijil/class_register/groups.html:5 +#: templates/alsijil/class_register/groups.html:8 #, fuzzy #| msgid "Group" msgid "My groups" msgstr "Grex" -#: menus.py:34 +#: menus.py:49 msgid "My overview" msgstr "" -#: menus.py:40 templates/alsijil/class_register/persons.html:7 -#: templates/alsijil/class_register/persons.html:11 +#: menus.py:60 templates/alsijil/class_register/persons.html:5 +#: templates/alsijil/class_register/persons.html:9 msgid "My students" msgstr "" -#: menus.py:46 templates/alsijil/absences/register.html:5 -#: templates/alsijil/absences/register.html:6 -msgid "Register absence" -msgstr "" - -#: menus.py:52 models.py:39 templates/alsijil/excuse_type/list.html:8 +#: menus.py:71 models.py:42 templates/alsijil/excuse_type/list.html:8 #: templates/alsijil/excuse_type/list.html:9 +#: templates/alsijil/partials/legend.html:26 msgid "Excuse types" msgstr "" -#: menus.py:58 models.py:75 models.py:210 -#: templates/alsijil/class_register/lesson.html:168 +#: menus.py:82 models.py:80 models.py:215 +#: templates/alsijil/class_register/lesson.html:247 #: templates/alsijil/extra_mark/list.html:8 #: templates/alsijil/extra_mark/list.html:9 +#: templates/alsijil/partials/legend.html:41 +#: templates/alsijil/partials/persons_with_stats.html:19 #: templates/alsijil/print/full_register.html:293 msgid "Extra marks" msgstr "" -#: models.py:25 models.py:196 +#: model_extensions.py:145 +msgid "Can view week overview of group class register" +msgstr "" + +#: model_extensions.py:149 +msgid "Can view lesson overview of group class register" +msgstr "" + +#: model_extensions.py:152 +msgid "Can view all personal notes of a group" +msgstr "" + +#: model_extensions.py:155 +msgid "Can edit all personal notes of a group" +msgstr "" + +#: model_extensions.py:158 +msgid "Can view all lesson documentation of a group" +msgstr "" + +#: model_extensions.py:161 +msgid "Can edit all lesson documentation of a group" +msgstr "" + +#: model_extensions.py:163 +msgid "Can view full register of a group" +msgstr "" + +#: model_extensions.py:165 +msgid "Can register an absence for all members of a group" +msgstr "" + +#: model_extensions.py:168 +msgid "Can register an absence for a person" +msgstr "" + +#: models.py:28 models.py:201 #, fuzzy #| msgid "First name" msgid "Short name" msgstr "Primus nomen" -#: models.py:27 models.py:198 +#: models.py:30 models.py:203 templates/alsijil/class_register/groups.html:20 +#: templates/alsijil/partials/persons_with_stats.html:14 +#: templates/alsijil/partials/persons_with_stats.html:24 msgid "Name" msgstr "" -#: models.py:55 models.py:126 +#: models.py:60 models.py:131 msgid "Year" msgstr "" -#: models.py:106 +#: models.py:111 #, fuzzy #| msgid "Person" msgid "Personal note" msgstr "Persona" -#: models.py:107 templates/alsijil/class_register/lesson.html:64 -#: templates/alsijil/class_register/lesson.html:156 -#: templates/alsijil/class_register/week_view.html:112 +#: models.py:112 templates/alsijil/class_register/lesson.html:101 +#: templates/alsijil/class_register/lesson.html:233 +#: templates/alsijil/class_register/week_view.html:68 +#: templates/alsijil/class_register/week_view.html:242 msgid "Personal notes" msgstr "" -#: models.py:132 templates/alsijil/class_register/week_view.html:64 +#: models.py:137 templates/alsijil/class_register/lesson.html:129 +#: templates/alsijil/class_register/week_view.html:90 +#: templates/alsijil/class_register/week_view.html:177 #: templates/alsijil/print/full_register.html:371 msgid "Lesson topic" msgstr "" -#: models.py:133 templates/alsijil/print/full_register.html:372 +#: models.py:138 templates/alsijil/class_register/lesson.html:137 +#: templates/alsijil/class_register/week_view.html:91 +#: templates/alsijil/class_register/week_view.html:183 +#: templates/alsijil/class_register/week_view.html:216 +#: templates/alsijil/print/full_register.html:372 msgid "Homework" msgstr "" -#: models.py:135 +#: models.py:140 templates/alsijil/class_register/lesson.html:145 +#: templates/alsijil/class_register/week_view.html:92 +#: templates/alsijil/class_register/week_view.html:189 +#: templates/alsijil/class_register/week_view.html:222 #, fuzzy #| msgid "Group" msgid "Group note" msgstr "Grex" -#: models.py:178 templates/alsijil/class_register/lesson.html:60 -#: templates/alsijil/class_register/lesson.html:143 +#: models.py:183 templates/alsijil/class_register/lesson.html:97 +#: templates/alsijil/class_register/lesson.html:120 msgid "Lesson documentation" msgstr "" -#: models.py:179 +#: models.py:184 templates/alsijil/class_register/week_view.html:67 msgid "Lesson documentations" msgstr "" -#: models.py:209 +#: models.py:214 msgid "Extra mark" msgstr "" +#: models.py:222 +msgid "Can view week overview" +msgstr "" + +#: models.py:223 +msgid "Can register absence" +msgstr "" + +#: models.py:224 +msgid "Can list all personal note filters" +msgstr "" + #: preferences.py:16 msgid "Block adding personal notes for cancelled lessons" msgstr "" -#: preferences.py:25 +#: preferences.py:24 +msgid "Allow users to view their own personal notes" +msgstr "" + +#: preferences.py:33 +msgid "Allow primary group owners to register future absences for students in their groups" +msgstr "" + +#: preferences.py:43 msgid "Carry over data from first lesson period to the following lesson periods in lessons over multiple periods" msgstr "" -#: preferences.py:28 +#: preferences.py:46 msgid "This will carry over data only if the data in the following periods are empty." msgstr "" -#: preferences.py:38 +#: preferences.py:56 msgid "Allow teachers to open lesson periods on the same day and not just at the beginning of the period" msgstr "" -#: preferences.py:41 +#: preferences.py:59 msgid "Lessons in the past are not affected by this setting, you can open them whenever you want." msgstr "" @@ -210,76 +273,160 @@ msgstr "" msgid "Edit" msgstr "" -#: tables.py:22 tables.py:42 +#: tables.py:22 tables.py:42 templates/alsijil/class_register/person.html:249 msgid "Delete" msgstr "" -#: templates/alsijil/class_register/groups.html:20 +#: templates/alsijil/absences/register.html:5 +#: templates/alsijil/absences/register.html:6 +#: templates/alsijil/class_register/person.html:30 +#: templates/alsijil/class_register/week_view.html:256 +#: templates/alsijil/partials/persons_with_stats.html:115 +msgid "Register absence" +msgstr "" + +#: templates/alsijil/absences/register.html:9 +#: templates/alsijil/class_register/lesson.html:242 +msgid "Person" +msgstr "Persona" + +#: templates/alsijil/class_register/groups.html:21 +msgid "Students" +msgstr "" + +#: templates/alsijil/class_register/groups.html:35 +#: templates/alsijil/class_register/groups.html:69 +#: templates/alsijil/class_register/week_view.html:40 +#: templates/alsijil/class_register/week_view.html:51 +msgid "Students list" +msgstr "" + +#: templates/alsijil/class_register/groups.html:39 +#: templates/alsijil/class_register/groups.html:75 +#: templates/alsijil/class_register/persons.html:27 +#: templates/alsijil/class_register/persons.html:43 +#: templates/alsijil/class_register/students_list.html:16 +#: templates/alsijil/class_register/students_list.html:35 +#: templates/alsijil/class_register/week_view.html:6 +msgid "Week view" +msgstr "" + +#: templates/alsijil/class_register/groups.html:44 +#: templates/alsijil/class_register/groups.html:82 +#: templates/alsijil/class_register/persons.html:31 +#: templates/alsijil/class_register/persons.html:50 +#: templates/alsijil/class_register/students_list.html:20 +#: templates/alsijil/class_register/students_list.html:42 +#: templates/alsijil/class_register/week_view.html:44 +#: templates/alsijil/class_register/week_view.html:58 +msgid "Generate printout" +msgstr "" + +#: templates/alsijil/class_register/groups.html:52 +#: templates/alsijil/class_register/groups.html:88 msgid "No groups available." msgstr "" -#: templates/alsijil/class_register/lesson.html:6 +#: templates/alsijil/class_register/groups.html:64 +msgid "students" +msgstr "" + +#: templates/alsijil/class_register/lesson.html:5 msgid "Lesson" msgstr "" -#: templates/alsijil/class_register/lesson.html:14 -#: templates/alsijil/class_register/lesson.html:83 -#, python-format -msgid "%(period)s. period" +#: templates/alsijil/class_register/lesson.html:20 +msgid "Back to week view" +msgstr "" + +#: templates/alsijil/class_register/lesson.html:29 +msgid "My previous lesson" msgstr "" #: templates/alsijil/class_register/lesson.html:38 -msgid "Previous lesson" +msgid "My next lesson" msgstr "" #: templates/alsijil/class_register/lesson.html:46 -msgid "Next lesson" +#: templates/alsijil/class_register/lesson.html:167 +#, python-format +msgid "%(period)s. period" +msgstr "" + +#: templates/alsijil/class_register/lesson.html:77 +#: templates/alsijil/class_register/lesson.html:359 +#, python-format +msgid "" +"\n" +" Previous %(subject)s lesson\n" +" " +msgstr "" + +#: templates/alsijil/class_register/lesson.html:85 +#: templates/alsijil/class_register/lesson.html:367 +#, python-format +msgid "" +"\n" +" Next %(subject)s lesson\n" +" " +msgstr "" + +#: templates/alsijil/class_register/lesson.html:107 +msgid "Previous lesson" msgstr "" -#: templates/alsijil/class_register/lesson.html:68 -#: templates/alsijil/class_register/lesson.html:249 +#: templates/alsijil/class_register/lesson.html:111 +#: templates/alsijil/class_register/lesson.html:342 msgid "Change history" msgstr "" -#: templates/alsijil/class_register/lesson.html:82 +#: templates/alsijil/class_register/lesson.html:166 msgid "Overview: Previous lesson" msgstr "" -#: templates/alsijil/class_register/lesson.html:89 +#: templates/alsijil/class_register/lesson.html:173 msgid "Lesson topic of previous lesson:" msgstr "" -#: templates/alsijil/class_register/lesson.html:96 +#: templates/alsijil/class_register/lesson.html:180 msgid "Homework for this lesson:" msgstr "" -#: templates/alsijil/class_register/lesson.html:103 +#: templates/alsijil/class_register/lesson.html:187 msgid "Group notes for previous lesson:" msgstr "" -#: templates/alsijil/class_register/lesson.html:110 +#: templates/alsijil/class_register/lesson.html:194 msgid "Absent persons:" msgstr "" -#: templates/alsijil/class_register/lesson.html:117 +#: templates/alsijil/class_register/lesson.html:201 msgid "Late persons:" msgstr "" -#: templates/alsijil/class_register/lesson.html:165 -#: templates/alsijil/class_register/person.html:86 +#: templates/alsijil/class_register/lesson.html:244 +#: templates/alsijil/class_register/person.html:110 +#: templates/alsijil/partials/persons_with_stats.html:17 +#: templates/alsijil/partials/persons_with_stats.html:34 +#: templates/alsijil/partials/persons_with_stats.html:91 #: templates/alsijil/print/full_register.html:287 msgid "Tardiness" msgstr "" -#: templates/alsijil/class_register/lesson.html:188 +#: templates/alsijil/class_register/lesson.html:267 msgid "Tardiness (in m)" msgstr "" -#: templates/alsijil/class_register/person.html:7 +#: templates/alsijil/class_register/person.html:8 msgid "Class register: person" msgstr "" -#: templates/alsijil/class_register/person.html:11 +#: templates/alsijil/class_register/person.html:16 +#: templates/alsijil/class_register/students_list.html:10 +msgid "Back" +msgstr "" + +#: templates/alsijil/class_register/person.html:19 #, python-format msgid "" "\n" @@ -287,120 +434,133 @@ msgid "" " " msgstr "" -#: templates/alsijil/class_register/person.html:19 +#: templates/alsijil/class_register/person.html:36 +#: templates/alsijil/partials/legend.html:14 msgid "Unexcused absences" msgstr "" -#: templates/alsijil/class_register/person.html:27 -#: templates/alsijil/class_register/person.html:44 -#: templates/alsijil/class_register/person.html:160 -#: templates/alsijil/class_register/person.html:202 +#: templates/alsijil/class_register/person.html:46 +#: templates/alsijil/class_register/person.html:65 +#: templates/alsijil/class_register/person.html:190 +#: templates/alsijil/class_register/person.html:237 msgid "Mark as" msgstr "" -#: templates/alsijil/class_register/person.html:30 -#: templates/alsijil/class_register/person.html:47 -#: templates/alsijil/class_register/person.html:163 -#: templates/alsijil/class_register/person.html:205 +#: templates/alsijil/class_register/person.html:49 +#: templates/alsijil/class_register/person.html:68 +#: templates/alsijil/class_register/person.html:193 +#: templates/alsijil/class_register/person.html:199 +#: templates/alsijil/class_register/person.html:240 +#: templates/alsijil/class_register/person.html:246 msgid "Delete note" msgstr "" -#: templates/alsijil/class_register/person.html:55 -msgid "There are unexcused lessons." +#: templates/alsijil/class_register/person.html:78 +msgid "There are no unexcused lessons." msgstr "" -#: templates/alsijil/class_register/person.html:59 +#: templates/alsijil/class_register/person.html:83 msgid "Statistics on absences, tardiness and remarks" msgstr "" -#: templates/alsijil/class_register/person.html:68 +#: templates/alsijil/class_register/person.html:92 +#: templates/alsijil/partials/legend.html:10 +#: templates/alsijil/partials/persons_with_stats.html:16 +#: templates/alsijil/partials/persons_with_stats.html:26 +#: templates/alsijil/partials/persons_with_stats.html:69 #: templates/alsijil/print/full_register.html:269 msgid "Absences" msgstr "" -#: templates/alsijil/class_register/person.html:72 +#: templates/alsijil/class_register/person.html:96 #: templates/alsijil/print/full_register.html:274 msgid "thereof" msgstr "" -#: templates/alsijil/class_register/person.html:82 +#: templates/alsijil/class_register/person.html:106 +#: templates/alsijil/partials/persons_with_stats.html:86 #: templates/alsijil/print/full_register.html:81 #: templates/alsijil/print/full_register.html:283 msgid "Unexcused" msgstr "" -#: templates/alsijil/class_register/person.html:102 +#: templates/alsijil/class_register/person.html:127 #: templates/alsijil/print/full_register.html:304 msgid "Relevant personal notes" msgstr "" -#: templates/alsijil/class_register/person.html:118 +#: templates/alsijil/class_register/person.html:143 #, python-format msgid "Week %(week)s" msgstr "" -#: templates/alsijil/class_register/person.html:126 -#: templates/alsijil/class_register/person.html:135 +#: templates/alsijil/class_register/person.html:152 +#: templates/alsijil/class_register/person.html:163 msgid "Mark all as" msgstr "" -#: templates/alsijil/class_register/person.html:187 +#: templates/alsijil/class_register/person.html:222 #, python-format msgid "%(late)s' late" msgstr "" -#: templates/alsijil/class_register/persons.html:22 -msgid "No students available." -msgstr "" - -#: templates/alsijil/class_register/week_view.html:6 -msgid "Week view" +#: templates/alsijil/class_register/students_list.html:5 +#: templates/alsijil/class_register/students_list.html:12 +#, python-format +msgid "Students list: %(group)s" msgstr "" -#: templates/alsijil/class_register/week_view.html:30 +#: templates/alsijil/class_register/week_view.html:23 msgid "Select" msgstr "" -#: templates/alsijil/class_register/week_view.html:38 +#: templates/alsijil/class_register/week_view.html:31 #, python-format msgid "" "CW %(week)s:\n" " %(instance)s" msgstr "" -#: templates/alsijil/class_register/week_view.html:58 +#: templates/alsijil/class_register/week_view.html:84 msgid "Period" msgstr "" -#: templates/alsijil/class_register/week_view.html:60 +#: templates/alsijil/class_register/week_view.html:86 #, fuzzy #| msgid "Group" msgid "Groups" msgstr "Grex" -#: templates/alsijil/class_register/week_view.html:62 +#: templates/alsijil/class_register/week_view.html:88 +#: templates/alsijil/class_register/week_view.html:163 #: templates/alsijil/print/full_register.html:169 #: templates/alsijil/print/full_register.html:200 msgid "Subject" msgstr "" -#: templates/alsijil/class_register/week_view.html:63 +#: templates/alsijil/class_register/week_view.html:89 +#: templates/alsijil/class_register/week_view.html:173 msgid "Teachers" msgstr "" -#: templates/alsijil/class_register/week_view.html:120 +#: templates/alsijil/class_register/week_view.html:262 msgid "unexcused" msgstr "" -#: templates/alsijil/class_register/week_view.html:123 +#: templates/alsijil/class_register/week_view.html:265 msgid "Summed up tardiness" msgstr "" -#: templates/alsijil/class_register/week_view.html:152 +#: templates/alsijil/class_register/week_view.html:268 +#: templates/alsijil/partials/persons_with_stats.html:94 +msgid "Count of tardiness" +msgstr "" + +#: templates/alsijil/class_register/week_view.html:297 msgid "No lessons available" msgstr "" -#: templates/alsijil/class_register/week_view.html:155 +#: templates/alsijil/class_register/week_view.html:300 msgid "" "\n" " There are no lessons for the selected group or teacher in this week.\n" @@ -409,7 +569,7 @@ msgstr "" #: templates/alsijil/excuse_type/create.html:6 #: templates/alsijil/excuse_type/create.html:7 -#: templates/alsijil/excuse_type/list.html:16 +#: templates/alsijil/excuse_type/list.html:18 msgid "Create excuse type" msgstr "" @@ -437,16 +597,33 @@ msgstr "" msgid "Edit extra mark" msgstr "" -#: templates/alsijil/partials/absences.html:4 +#: templates/alsijil/partials/absences.html:6 +#: templates/alsijil/partials/persons_with_stats.html:27 +#: templates/alsijil/partials/persons_with_stats.html:44 #: templates/alsijil/print/full_register.html:126 msgid "(e)" msgstr "" -#: templates/alsijil/partials/absences.html:4 +#: templates/alsijil/partials/absences.html:6 +#: templates/alsijil/partials/persons_with_stats.html:33 +#: templates/alsijil/partials/persons_with_stats.html:50 #: templates/alsijil/print/full_register.html:130 msgid "(u)" msgstr "" +#: templates/alsijil/partials/legend.html:4 +msgid "Legend" +msgstr "" + +#: templates/alsijil/partials/legend.html:7 +#: templates/alsijil/print/full_register.html:71 +msgid "General" +msgstr "" + +#: templates/alsijil/partials/legend.html:18 +msgid "Excused absences" +msgstr "" + #: templates/alsijil/partials/lesson_status_icon.html:6 msgid "Data complete" msgstr "" @@ -475,6 +652,29 @@ msgstr "" msgid "e" msgstr "" +#: templates/alsijil/partials/persons_with_stats.html:7 +msgid "No students available." +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:15 +#: templates/alsijil/partials/persons_with_stats.html:25 +#, fuzzy +#| msgid "Group" +msgid "Primary group" +msgstr "Grex" + +#: templates/alsijil/partials/persons_with_stats.html:43 +msgid "Sum" +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:107 +msgid "Show more details" +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:108 +msgid "Details" +msgstr "" + #: templates/alsijil/print/full_register.html:6 msgid "Class register:" msgstr "" @@ -522,10 +722,6 @@ msgstr "" msgid "Abbreviations" msgstr "" -#: templates/alsijil/print/full_register.html:71 -msgid "General" -msgstr "" - #: templates/alsijil/print/full_register.html:78 msgid "Late" msgstr "" @@ -640,63 +836,59 @@ msgstr "" msgid "Notes" msgstr "" -#: views.py:78 +#: views.py:69 msgid "You either selected an invalid lesson or there is currently no lesson in progress." msgstr "" -#: views.py:96 +#: views.py:95 msgid "You are not allowed to create a lesson documentation for a lesson in the future." msgstr "" -#: views.py:122 +#: views.py:133 msgid "The lesson documentation has been saved." msgstr "" -#: views.py:143 +#: views.py:156 msgid "The personal notes have been saved." msgstr "" -#: views.py:351 -msgid "There is no current school term." -msgstr "" - -#: views.py:532 +#: views.py:587 msgid "The absences have been marked as excused." msgstr "" -#: views.py:548 +#: views.py:605 msgid "The absence has been marked as excused." msgstr "" -#: views.py:653 +#: views.py:735 msgid "The absence has been saved." msgstr "" -#: views.py:670 +#: views.py:754 msgid "The personal note has been deleted." msgstr "" -#: views.py:691 +#: views.py:775 msgid "The extra mark has been created." msgstr "" -#: views.py:702 +#: views.py:786 msgid "The extra mark has been saved." msgstr "" -#: views.py:712 +#: views.py:796 msgid "The extra mark has been deleted." msgstr "" -#: views.py:732 +#: views.py:816 msgid "The excuse type has been created." msgstr "" -#: views.py:743 +#: views.py:827 msgid "The excuse type has been saved." msgstr "" -#: views.py:753 +#: views.py:837 msgid "The excuse type has been deleted." msgstr "" diff --git a/aleksis/apps/alsijil/locale/nb_NO/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/nb_NO/LC_MESSAGES/django.po index ae7cc207f15c81a12de3725d3b9587d776269cd0..3133277a307b8c1cf68500bde39fe4512feba932 100644 --- a/aleksis/apps/alsijil/locale/nb_NO/LC_MESSAGES/django.po +++ b/aleksis/apps/alsijil/locale/nb_NO/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-11 11:08+0200\n" +"POT-Creation-Date: 2020-11-14 12:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -17,11 +17,12 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: forms.py:26 +#: forms.py:29 msgid "Homework for the next lesson" msgstr "" -#: forms.py:51 templates/alsijil/print/full_register.html:199 +#: forms.py:54 templates/alsijil/class_register/week_view.html:168 +#: templates/alsijil/print/full_register.html:199 msgid "Group" msgstr "" @@ -30,57 +31,53 @@ msgstr "" msgid "Teacher" msgstr "" -#: forms.py:74 +#: forms.py:72 msgid "You can't select a group and a teacher both." msgstr "" -#: forms.py:100 +#: forms.py:125 msgid "Start date" msgstr "" -#: forms.py:101 +#: forms.py:126 msgid "End date" msgstr "" -#: forms.py:102 +#: forms.py:127 msgid "Start period" msgstr "" -#: forms.py:103 +#: forms.py:128 msgid "End period" msgstr "" -#: forms.py:105 templates/alsijil/class_register/lesson.html:163 -msgid "Person" -msgstr "" - -#: forms.py:107 templates/alsijil/class_register/lesson.html:164 -#: templates/alsijil/class_register/person.html:172 -#: templates/alsijil/class_register/week_view.html:119 +#: forms.py:129 templates/alsijil/class_register/lesson.html:243 +#: templates/alsijil/class_register/person.html:207 +#: templates/alsijil/class_register/week_view.html:261 #: templates/alsijil/print/full_register.html:75 #: templates/alsijil/print/full_register.html:312 msgid "Absent" msgstr "" -#: forms.py:108 templates/alsijil/class_register/lesson.html:166 -#: templates/alsijil/class_register/person.html:74 -#: templates/alsijil/class_register/person.html:180 +#: forms.py:130 templates/alsijil/class_register/lesson.html:245 +#: templates/alsijil/class_register/person.html:98 +#: templates/alsijil/class_register/person.html:215 #: templates/alsijil/partials/mark_as_buttons.html:2 #: templates/alsijil/partials/mark_as_buttons.html:3 +#: templates/alsijil/partials/persons_with_stats.html:74 #: templates/alsijil/print/full_register.html:84 #: templates/alsijil/print/full_register.html:275 msgid "Excused" msgstr "" -#: forms.py:110 models.py:38 models.py:69 -#: templates/alsijil/class_register/lesson.html:167 -#: templates/alsijil/class_register/lesson.html:202 +#: forms.py:132 models.py:41 models.py:74 +#: templates/alsijil/class_register/lesson.html:246 +#: templates/alsijil/class_register/lesson.html:281 msgid "Excuse type" msgstr "" -#: forms.py:115 templates/alsijil/class_register/lesson.html:170 -#: templates/alsijil/class_register/lesson.html:223 -#: templates/alsijil/class_register/lesson.html:231 +#: forms.py:137 templates/alsijil/class_register/lesson.html:248 +#: templates/alsijil/class_register/lesson.html:302 #: templates/alsijil/print/full_register.html:314 msgid "Remarks" msgstr "" @@ -93,107 +90,173 @@ msgstr "" msgid "Current lesson" msgstr "" -#: menus.py:22 +#: menus.py:27 msgid "Current week" msgstr "" -#: menus.py:28 templates/alsijil/class_register/groups.html:5 -#: templates/alsijil/class_register/groups.html:9 +#: menus.py:38 templates/alsijil/class_register/groups.html:5 +#: templates/alsijil/class_register/groups.html:8 msgid "My groups" msgstr "" -#: menus.py:34 +#: menus.py:49 msgid "My overview" msgstr "" -#: menus.py:40 templates/alsijil/class_register/persons.html:7 -#: templates/alsijil/class_register/persons.html:11 +#: menus.py:60 templates/alsijil/class_register/persons.html:5 +#: templates/alsijil/class_register/persons.html:9 msgid "My students" msgstr "" -#: menus.py:46 templates/alsijil/absences/register.html:5 -#: templates/alsijil/absences/register.html:6 -msgid "Register absence" -msgstr "" - -#: menus.py:52 models.py:39 templates/alsijil/excuse_type/list.html:8 +#: menus.py:71 models.py:42 templates/alsijil/excuse_type/list.html:8 #: templates/alsijil/excuse_type/list.html:9 +#: templates/alsijil/partials/legend.html:26 msgid "Excuse types" msgstr "" -#: menus.py:58 models.py:75 models.py:210 -#: templates/alsijil/class_register/lesson.html:168 +#: menus.py:82 models.py:80 models.py:215 +#: templates/alsijil/class_register/lesson.html:247 #: templates/alsijil/extra_mark/list.html:8 #: templates/alsijil/extra_mark/list.html:9 +#: templates/alsijil/partials/legend.html:41 +#: templates/alsijil/partials/persons_with_stats.html:19 #: templates/alsijil/print/full_register.html:293 msgid "Extra marks" msgstr "" -#: models.py:25 models.py:196 +#: model_extensions.py:145 +msgid "Can view week overview of group class register" +msgstr "" + +#: model_extensions.py:149 +msgid "Can view lesson overview of group class register" +msgstr "" + +#: model_extensions.py:152 +msgid "Can view all personal notes of a group" +msgstr "" + +#: model_extensions.py:155 +msgid "Can edit all personal notes of a group" +msgstr "" + +#: model_extensions.py:158 +msgid "Can view all lesson documentation of a group" +msgstr "" + +#: model_extensions.py:161 +msgid "Can edit all lesson documentation of a group" +msgstr "" + +#: model_extensions.py:163 +msgid "Can view full register of a group" +msgstr "" + +#: model_extensions.py:165 +msgid "Can register an absence for all members of a group" +msgstr "" + +#: model_extensions.py:168 +msgid "Can register an absence for a person" +msgstr "" + +#: models.py:28 models.py:201 msgid "Short name" msgstr "" -#: models.py:27 models.py:198 +#: models.py:30 models.py:203 templates/alsijil/class_register/groups.html:20 +#: templates/alsijil/partials/persons_with_stats.html:14 +#: templates/alsijil/partials/persons_with_stats.html:24 msgid "Name" msgstr "" -#: models.py:55 models.py:126 +#: models.py:60 models.py:131 msgid "Year" msgstr "" -#: models.py:106 +#: models.py:111 msgid "Personal note" msgstr "" -#: models.py:107 templates/alsijil/class_register/lesson.html:64 -#: templates/alsijil/class_register/lesson.html:156 -#: templates/alsijil/class_register/week_view.html:112 +#: models.py:112 templates/alsijil/class_register/lesson.html:101 +#: templates/alsijil/class_register/lesson.html:233 +#: templates/alsijil/class_register/week_view.html:68 +#: templates/alsijil/class_register/week_view.html:242 msgid "Personal notes" msgstr "" -#: models.py:132 templates/alsijil/class_register/week_view.html:64 +#: models.py:137 templates/alsijil/class_register/lesson.html:129 +#: templates/alsijil/class_register/week_view.html:90 +#: templates/alsijil/class_register/week_view.html:177 #: templates/alsijil/print/full_register.html:371 msgid "Lesson topic" msgstr "" -#: models.py:133 templates/alsijil/print/full_register.html:372 +#: models.py:138 templates/alsijil/class_register/lesson.html:137 +#: templates/alsijil/class_register/week_view.html:91 +#: templates/alsijil/class_register/week_view.html:183 +#: templates/alsijil/class_register/week_view.html:216 +#: templates/alsijil/print/full_register.html:372 msgid "Homework" msgstr "" -#: models.py:135 +#: models.py:140 templates/alsijil/class_register/lesson.html:145 +#: templates/alsijil/class_register/week_view.html:92 +#: templates/alsijil/class_register/week_view.html:189 +#: templates/alsijil/class_register/week_view.html:222 msgid "Group note" msgstr "" -#: models.py:178 templates/alsijil/class_register/lesson.html:60 -#: templates/alsijil/class_register/lesson.html:143 +#: models.py:183 templates/alsijil/class_register/lesson.html:97 +#: templates/alsijil/class_register/lesson.html:120 msgid "Lesson documentation" msgstr "" -#: models.py:179 +#: models.py:184 templates/alsijil/class_register/week_view.html:67 msgid "Lesson documentations" msgstr "" -#: models.py:209 +#: models.py:214 msgid "Extra mark" msgstr "" +#: models.py:222 +msgid "Can view week overview" +msgstr "" + +#: models.py:223 +msgid "Can register absence" +msgstr "" + +#: models.py:224 +msgid "Can list all personal note filters" +msgstr "" + #: preferences.py:16 msgid "Block adding personal notes for cancelled lessons" msgstr "" -#: preferences.py:25 +#: preferences.py:24 +msgid "Allow users to view their own personal notes" +msgstr "" + +#: preferences.py:33 +msgid "Allow primary group owners to register future absences for students in their groups" +msgstr "" + +#: preferences.py:43 msgid "Carry over data from first lesson period to the following lesson periods in lessons over multiple periods" msgstr "" -#: preferences.py:28 +#: preferences.py:46 msgid "This will carry over data only if the data in the following periods are empty." msgstr "" -#: preferences.py:38 +#: preferences.py:56 msgid "Allow teachers to open lesson periods on the same day and not just at the beginning of the period" msgstr "" -#: preferences.py:41 +#: preferences.py:59 msgid "Lessons in the past are not affected by this setting, you can open them whenever you want." msgstr "" @@ -201,76 +264,160 @@ msgstr "" msgid "Edit" msgstr "" -#: tables.py:22 tables.py:42 +#: tables.py:22 tables.py:42 templates/alsijil/class_register/person.html:249 msgid "Delete" msgstr "" -#: templates/alsijil/class_register/groups.html:20 +#: templates/alsijil/absences/register.html:5 +#: templates/alsijil/absences/register.html:6 +#: templates/alsijil/class_register/person.html:30 +#: templates/alsijil/class_register/week_view.html:256 +#: templates/alsijil/partials/persons_with_stats.html:115 +msgid "Register absence" +msgstr "" + +#: templates/alsijil/absences/register.html:9 +#: templates/alsijil/class_register/lesson.html:242 +msgid "Person" +msgstr "" + +#: templates/alsijil/class_register/groups.html:21 +msgid "Students" +msgstr "" + +#: templates/alsijil/class_register/groups.html:35 +#: templates/alsijil/class_register/groups.html:69 +#: templates/alsijil/class_register/week_view.html:40 +#: templates/alsijil/class_register/week_view.html:51 +msgid "Students list" +msgstr "" + +#: templates/alsijil/class_register/groups.html:39 +#: templates/alsijil/class_register/groups.html:75 +#: templates/alsijil/class_register/persons.html:27 +#: templates/alsijil/class_register/persons.html:43 +#: templates/alsijil/class_register/students_list.html:16 +#: templates/alsijil/class_register/students_list.html:35 +#: templates/alsijil/class_register/week_view.html:6 +msgid "Week view" +msgstr "" + +#: templates/alsijil/class_register/groups.html:44 +#: templates/alsijil/class_register/groups.html:82 +#: templates/alsijil/class_register/persons.html:31 +#: templates/alsijil/class_register/persons.html:50 +#: templates/alsijil/class_register/students_list.html:20 +#: templates/alsijil/class_register/students_list.html:42 +#: templates/alsijil/class_register/week_view.html:44 +#: templates/alsijil/class_register/week_view.html:58 +msgid "Generate printout" +msgstr "" + +#: templates/alsijil/class_register/groups.html:52 +#: templates/alsijil/class_register/groups.html:88 msgid "No groups available." msgstr "" -#: templates/alsijil/class_register/lesson.html:6 +#: templates/alsijil/class_register/groups.html:64 +msgid "students" +msgstr "" + +#: templates/alsijil/class_register/lesson.html:5 msgid "Lesson" msgstr "" -#: templates/alsijil/class_register/lesson.html:14 -#: templates/alsijil/class_register/lesson.html:83 -#, python-format -msgid "%(period)s. period" +#: templates/alsijil/class_register/lesson.html:20 +msgid "Back to week view" +msgstr "" + +#: templates/alsijil/class_register/lesson.html:29 +msgid "My previous lesson" msgstr "" #: templates/alsijil/class_register/lesson.html:38 -msgid "Previous lesson" +msgid "My next lesson" msgstr "" #: templates/alsijil/class_register/lesson.html:46 -msgid "Next lesson" +#: templates/alsijil/class_register/lesson.html:167 +#, python-format +msgid "%(period)s. period" +msgstr "" + +#: templates/alsijil/class_register/lesson.html:77 +#: templates/alsijil/class_register/lesson.html:359 +#, python-format +msgid "" +"\n" +" Previous %(subject)s lesson\n" +" " +msgstr "" + +#: templates/alsijil/class_register/lesson.html:85 +#: templates/alsijil/class_register/lesson.html:367 +#, python-format +msgid "" +"\n" +" Next %(subject)s lesson\n" +" " +msgstr "" + +#: templates/alsijil/class_register/lesson.html:107 +msgid "Previous lesson" msgstr "" -#: templates/alsijil/class_register/lesson.html:68 -#: templates/alsijil/class_register/lesson.html:249 +#: templates/alsijil/class_register/lesson.html:111 +#: templates/alsijil/class_register/lesson.html:342 msgid "Change history" msgstr "" -#: templates/alsijil/class_register/lesson.html:82 +#: templates/alsijil/class_register/lesson.html:166 msgid "Overview: Previous lesson" msgstr "" -#: templates/alsijil/class_register/lesson.html:89 +#: templates/alsijil/class_register/lesson.html:173 msgid "Lesson topic of previous lesson:" msgstr "" -#: templates/alsijil/class_register/lesson.html:96 +#: templates/alsijil/class_register/lesson.html:180 msgid "Homework for this lesson:" msgstr "" -#: templates/alsijil/class_register/lesson.html:103 +#: templates/alsijil/class_register/lesson.html:187 msgid "Group notes for previous lesson:" msgstr "" -#: templates/alsijil/class_register/lesson.html:110 +#: templates/alsijil/class_register/lesson.html:194 msgid "Absent persons:" msgstr "" -#: templates/alsijil/class_register/lesson.html:117 +#: templates/alsijil/class_register/lesson.html:201 msgid "Late persons:" msgstr "" -#: templates/alsijil/class_register/lesson.html:165 -#: templates/alsijil/class_register/person.html:86 +#: templates/alsijil/class_register/lesson.html:244 +#: templates/alsijil/class_register/person.html:110 +#: templates/alsijil/partials/persons_with_stats.html:17 +#: templates/alsijil/partials/persons_with_stats.html:34 +#: templates/alsijil/partials/persons_with_stats.html:91 #: templates/alsijil/print/full_register.html:287 msgid "Tardiness" msgstr "" -#: templates/alsijil/class_register/lesson.html:188 +#: templates/alsijil/class_register/lesson.html:267 msgid "Tardiness (in m)" msgstr "" -#: templates/alsijil/class_register/person.html:7 +#: templates/alsijil/class_register/person.html:8 msgid "Class register: person" msgstr "" -#: templates/alsijil/class_register/person.html:11 +#: templates/alsijil/class_register/person.html:16 +#: templates/alsijil/class_register/students_list.html:10 +msgid "Back" +msgstr "" + +#: templates/alsijil/class_register/person.html:19 #, python-format msgid "" "\n" @@ -278,118 +425,131 @@ msgid "" " " msgstr "" -#: templates/alsijil/class_register/person.html:19 +#: templates/alsijil/class_register/person.html:36 +#: templates/alsijil/partials/legend.html:14 msgid "Unexcused absences" msgstr "" -#: templates/alsijil/class_register/person.html:27 -#: templates/alsijil/class_register/person.html:44 -#: templates/alsijil/class_register/person.html:160 -#: templates/alsijil/class_register/person.html:202 +#: templates/alsijil/class_register/person.html:46 +#: templates/alsijil/class_register/person.html:65 +#: templates/alsijil/class_register/person.html:190 +#: templates/alsijil/class_register/person.html:237 msgid "Mark as" msgstr "" -#: templates/alsijil/class_register/person.html:30 -#: templates/alsijil/class_register/person.html:47 -#: templates/alsijil/class_register/person.html:163 -#: templates/alsijil/class_register/person.html:205 +#: templates/alsijil/class_register/person.html:49 +#: templates/alsijil/class_register/person.html:68 +#: templates/alsijil/class_register/person.html:193 +#: templates/alsijil/class_register/person.html:199 +#: templates/alsijil/class_register/person.html:240 +#: templates/alsijil/class_register/person.html:246 msgid "Delete note" msgstr "" -#: templates/alsijil/class_register/person.html:55 -msgid "There are unexcused lessons." +#: templates/alsijil/class_register/person.html:78 +msgid "There are no unexcused lessons." msgstr "" -#: templates/alsijil/class_register/person.html:59 +#: templates/alsijil/class_register/person.html:83 msgid "Statistics on absences, tardiness and remarks" msgstr "" -#: templates/alsijil/class_register/person.html:68 +#: templates/alsijil/class_register/person.html:92 +#: templates/alsijil/partials/legend.html:10 +#: templates/alsijil/partials/persons_with_stats.html:16 +#: templates/alsijil/partials/persons_with_stats.html:26 +#: templates/alsijil/partials/persons_with_stats.html:69 #: templates/alsijil/print/full_register.html:269 msgid "Absences" msgstr "" -#: templates/alsijil/class_register/person.html:72 +#: templates/alsijil/class_register/person.html:96 #: templates/alsijil/print/full_register.html:274 msgid "thereof" msgstr "" -#: templates/alsijil/class_register/person.html:82 +#: templates/alsijil/class_register/person.html:106 +#: templates/alsijil/partials/persons_with_stats.html:86 #: templates/alsijil/print/full_register.html:81 #: templates/alsijil/print/full_register.html:283 msgid "Unexcused" msgstr "" -#: templates/alsijil/class_register/person.html:102 +#: templates/alsijil/class_register/person.html:127 #: templates/alsijil/print/full_register.html:304 msgid "Relevant personal notes" msgstr "" -#: templates/alsijil/class_register/person.html:118 +#: templates/alsijil/class_register/person.html:143 #, python-format msgid "Week %(week)s" msgstr "" -#: templates/alsijil/class_register/person.html:126 -#: templates/alsijil/class_register/person.html:135 +#: templates/alsijil/class_register/person.html:152 +#: templates/alsijil/class_register/person.html:163 msgid "Mark all as" msgstr "" -#: templates/alsijil/class_register/person.html:187 +#: templates/alsijil/class_register/person.html:222 #, python-format msgid "%(late)s' late" msgstr "" -#: templates/alsijil/class_register/persons.html:22 -msgid "No students available." -msgstr "" - -#: templates/alsijil/class_register/week_view.html:6 -msgid "Week view" +#: templates/alsijil/class_register/students_list.html:5 +#: templates/alsijil/class_register/students_list.html:12 +#, python-format +msgid "Students list: %(group)s" msgstr "" -#: templates/alsijil/class_register/week_view.html:30 +#: templates/alsijil/class_register/week_view.html:23 msgid "Select" msgstr "" -#: templates/alsijil/class_register/week_view.html:38 +#: templates/alsijil/class_register/week_view.html:31 #, python-format msgid "" "CW %(week)s:\n" " %(instance)s" msgstr "" -#: templates/alsijil/class_register/week_view.html:58 +#: templates/alsijil/class_register/week_view.html:84 msgid "Period" msgstr "" -#: templates/alsijil/class_register/week_view.html:60 +#: templates/alsijil/class_register/week_view.html:86 msgid "Groups" msgstr "" -#: templates/alsijil/class_register/week_view.html:62 +#: templates/alsijil/class_register/week_view.html:88 +#: templates/alsijil/class_register/week_view.html:163 #: templates/alsijil/print/full_register.html:169 #: templates/alsijil/print/full_register.html:200 msgid "Subject" msgstr "" -#: templates/alsijil/class_register/week_view.html:63 +#: templates/alsijil/class_register/week_view.html:89 +#: templates/alsijil/class_register/week_view.html:173 msgid "Teachers" msgstr "" -#: templates/alsijil/class_register/week_view.html:120 +#: templates/alsijil/class_register/week_view.html:262 msgid "unexcused" msgstr "" -#: templates/alsijil/class_register/week_view.html:123 +#: templates/alsijil/class_register/week_view.html:265 msgid "Summed up tardiness" msgstr "" -#: templates/alsijil/class_register/week_view.html:152 +#: templates/alsijil/class_register/week_view.html:268 +#: templates/alsijil/partials/persons_with_stats.html:94 +msgid "Count of tardiness" +msgstr "" + +#: templates/alsijil/class_register/week_view.html:297 msgid "No lessons available" msgstr "" -#: templates/alsijil/class_register/week_view.html:155 +#: templates/alsijil/class_register/week_view.html:300 msgid "" "\n" " There are no lessons for the selected group or teacher in this week.\n" @@ -398,7 +558,7 @@ msgstr "" #: templates/alsijil/excuse_type/create.html:6 #: templates/alsijil/excuse_type/create.html:7 -#: templates/alsijil/excuse_type/list.html:16 +#: templates/alsijil/excuse_type/list.html:18 msgid "Create excuse type" msgstr "" @@ -426,16 +586,33 @@ msgstr "" msgid "Edit extra mark" msgstr "" -#: templates/alsijil/partials/absences.html:4 +#: templates/alsijil/partials/absences.html:6 +#: templates/alsijil/partials/persons_with_stats.html:27 +#: templates/alsijil/partials/persons_with_stats.html:44 #: templates/alsijil/print/full_register.html:126 msgid "(e)" msgstr "" -#: templates/alsijil/partials/absences.html:4 +#: templates/alsijil/partials/absences.html:6 +#: templates/alsijil/partials/persons_with_stats.html:33 +#: templates/alsijil/partials/persons_with_stats.html:50 #: templates/alsijil/print/full_register.html:130 msgid "(u)" msgstr "" +#: templates/alsijil/partials/legend.html:4 +msgid "Legend" +msgstr "" + +#: templates/alsijil/partials/legend.html:7 +#: templates/alsijil/print/full_register.html:71 +msgid "General" +msgstr "" + +#: templates/alsijil/partials/legend.html:18 +msgid "Excused absences" +msgstr "" + #: templates/alsijil/partials/lesson_status_icon.html:6 msgid "Data complete" msgstr "" @@ -464,6 +641,27 @@ msgstr "" msgid "e" msgstr "" +#: templates/alsijil/partials/persons_with_stats.html:7 +msgid "No students available." +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:15 +#: templates/alsijil/partials/persons_with_stats.html:25 +msgid "Primary group" +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:43 +msgid "Sum" +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:107 +msgid "Show more details" +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:108 +msgid "Details" +msgstr "" + #: templates/alsijil/print/full_register.html:6 msgid "Class register:" msgstr "" @@ -511,10 +709,6 @@ msgstr "" msgid "Abbreviations" msgstr "" -#: templates/alsijil/print/full_register.html:71 -msgid "General" -msgstr "" - #: templates/alsijil/print/full_register.html:78 msgid "Late" msgstr "" @@ -629,62 +823,58 @@ msgstr "" msgid "Notes" msgstr "" -#: views.py:78 +#: views.py:69 msgid "You either selected an invalid lesson or there is currently no lesson in progress." msgstr "" -#: views.py:96 +#: views.py:95 msgid "You are not allowed to create a lesson documentation for a lesson in the future." msgstr "" -#: views.py:122 +#: views.py:133 msgid "The lesson documentation has been saved." msgstr "" -#: views.py:143 +#: views.py:156 msgid "The personal notes have been saved." msgstr "" -#: views.py:351 -msgid "There is no current school term." -msgstr "" - -#: views.py:532 +#: views.py:587 msgid "The absences have been marked as excused." msgstr "" -#: views.py:548 +#: views.py:605 msgid "The absence has been marked as excused." msgstr "" -#: views.py:653 +#: views.py:735 msgid "The absence has been saved." msgstr "" -#: views.py:670 +#: views.py:754 msgid "The personal note has been deleted." msgstr "" -#: views.py:691 +#: views.py:775 msgid "The extra mark has been created." msgstr "" -#: views.py:702 +#: views.py:786 msgid "The extra mark has been saved." msgstr "" -#: views.py:712 +#: views.py:796 msgid "The extra mark has been deleted." msgstr "" -#: views.py:732 +#: views.py:816 msgid "The excuse type has been created." msgstr "" -#: views.py:743 +#: views.py:827 msgid "The excuse type has been saved." msgstr "" -#: views.py:753 +#: views.py:837 msgid "The excuse type has been deleted." msgstr "" diff --git a/aleksis/apps/alsijil/locale/tr_TR/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/tr_TR/LC_MESSAGES/django.po index ae7cc207f15c81a12de3725d3b9587d776269cd0..3133277a307b8c1cf68500bde39fe4512feba932 100644 --- a/aleksis/apps/alsijil/locale/tr_TR/LC_MESSAGES/django.po +++ b/aleksis/apps/alsijil/locale/tr_TR/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-11 11:08+0200\n" +"POT-Creation-Date: 2020-11-14 12:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -17,11 +17,12 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: forms.py:26 +#: forms.py:29 msgid "Homework for the next lesson" msgstr "" -#: forms.py:51 templates/alsijil/print/full_register.html:199 +#: forms.py:54 templates/alsijil/class_register/week_view.html:168 +#: templates/alsijil/print/full_register.html:199 msgid "Group" msgstr "" @@ -30,57 +31,53 @@ msgstr "" msgid "Teacher" msgstr "" -#: forms.py:74 +#: forms.py:72 msgid "You can't select a group and a teacher both." msgstr "" -#: forms.py:100 +#: forms.py:125 msgid "Start date" msgstr "" -#: forms.py:101 +#: forms.py:126 msgid "End date" msgstr "" -#: forms.py:102 +#: forms.py:127 msgid "Start period" msgstr "" -#: forms.py:103 +#: forms.py:128 msgid "End period" msgstr "" -#: forms.py:105 templates/alsijil/class_register/lesson.html:163 -msgid "Person" -msgstr "" - -#: forms.py:107 templates/alsijil/class_register/lesson.html:164 -#: templates/alsijil/class_register/person.html:172 -#: templates/alsijil/class_register/week_view.html:119 +#: forms.py:129 templates/alsijil/class_register/lesson.html:243 +#: templates/alsijil/class_register/person.html:207 +#: templates/alsijil/class_register/week_view.html:261 #: templates/alsijil/print/full_register.html:75 #: templates/alsijil/print/full_register.html:312 msgid "Absent" msgstr "" -#: forms.py:108 templates/alsijil/class_register/lesson.html:166 -#: templates/alsijil/class_register/person.html:74 -#: templates/alsijil/class_register/person.html:180 +#: forms.py:130 templates/alsijil/class_register/lesson.html:245 +#: templates/alsijil/class_register/person.html:98 +#: templates/alsijil/class_register/person.html:215 #: templates/alsijil/partials/mark_as_buttons.html:2 #: templates/alsijil/partials/mark_as_buttons.html:3 +#: templates/alsijil/partials/persons_with_stats.html:74 #: templates/alsijil/print/full_register.html:84 #: templates/alsijil/print/full_register.html:275 msgid "Excused" msgstr "" -#: forms.py:110 models.py:38 models.py:69 -#: templates/alsijil/class_register/lesson.html:167 -#: templates/alsijil/class_register/lesson.html:202 +#: forms.py:132 models.py:41 models.py:74 +#: templates/alsijil/class_register/lesson.html:246 +#: templates/alsijil/class_register/lesson.html:281 msgid "Excuse type" msgstr "" -#: forms.py:115 templates/alsijil/class_register/lesson.html:170 -#: templates/alsijil/class_register/lesson.html:223 -#: templates/alsijil/class_register/lesson.html:231 +#: forms.py:137 templates/alsijil/class_register/lesson.html:248 +#: templates/alsijil/class_register/lesson.html:302 #: templates/alsijil/print/full_register.html:314 msgid "Remarks" msgstr "" @@ -93,107 +90,173 @@ msgstr "" msgid "Current lesson" msgstr "" -#: menus.py:22 +#: menus.py:27 msgid "Current week" msgstr "" -#: menus.py:28 templates/alsijil/class_register/groups.html:5 -#: templates/alsijil/class_register/groups.html:9 +#: menus.py:38 templates/alsijil/class_register/groups.html:5 +#: templates/alsijil/class_register/groups.html:8 msgid "My groups" msgstr "" -#: menus.py:34 +#: menus.py:49 msgid "My overview" msgstr "" -#: menus.py:40 templates/alsijil/class_register/persons.html:7 -#: templates/alsijil/class_register/persons.html:11 +#: menus.py:60 templates/alsijil/class_register/persons.html:5 +#: templates/alsijil/class_register/persons.html:9 msgid "My students" msgstr "" -#: menus.py:46 templates/alsijil/absences/register.html:5 -#: templates/alsijil/absences/register.html:6 -msgid "Register absence" -msgstr "" - -#: menus.py:52 models.py:39 templates/alsijil/excuse_type/list.html:8 +#: menus.py:71 models.py:42 templates/alsijil/excuse_type/list.html:8 #: templates/alsijil/excuse_type/list.html:9 +#: templates/alsijil/partials/legend.html:26 msgid "Excuse types" msgstr "" -#: menus.py:58 models.py:75 models.py:210 -#: templates/alsijil/class_register/lesson.html:168 +#: menus.py:82 models.py:80 models.py:215 +#: templates/alsijil/class_register/lesson.html:247 #: templates/alsijil/extra_mark/list.html:8 #: templates/alsijil/extra_mark/list.html:9 +#: templates/alsijil/partials/legend.html:41 +#: templates/alsijil/partials/persons_with_stats.html:19 #: templates/alsijil/print/full_register.html:293 msgid "Extra marks" msgstr "" -#: models.py:25 models.py:196 +#: model_extensions.py:145 +msgid "Can view week overview of group class register" +msgstr "" + +#: model_extensions.py:149 +msgid "Can view lesson overview of group class register" +msgstr "" + +#: model_extensions.py:152 +msgid "Can view all personal notes of a group" +msgstr "" + +#: model_extensions.py:155 +msgid "Can edit all personal notes of a group" +msgstr "" + +#: model_extensions.py:158 +msgid "Can view all lesson documentation of a group" +msgstr "" + +#: model_extensions.py:161 +msgid "Can edit all lesson documentation of a group" +msgstr "" + +#: model_extensions.py:163 +msgid "Can view full register of a group" +msgstr "" + +#: model_extensions.py:165 +msgid "Can register an absence for all members of a group" +msgstr "" + +#: model_extensions.py:168 +msgid "Can register an absence for a person" +msgstr "" + +#: models.py:28 models.py:201 msgid "Short name" msgstr "" -#: models.py:27 models.py:198 +#: models.py:30 models.py:203 templates/alsijil/class_register/groups.html:20 +#: templates/alsijil/partials/persons_with_stats.html:14 +#: templates/alsijil/partials/persons_with_stats.html:24 msgid "Name" msgstr "" -#: models.py:55 models.py:126 +#: models.py:60 models.py:131 msgid "Year" msgstr "" -#: models.py:106 +#: models.py:111 msgid "Personal note" msgstr "" -#: models.py:107 templates/alsijil/class_register/lesson.html:64 -#: templates/alsijil/class_register/lesson.html:156 -#: templates/alsijil/class_register/week_view.html:112 +#: models.py:112 templates/alsijil/class_register/lesson.html:101 +#: templates/alsijil/class_register/lesson.html:233 +#: templates/alsijil/class_register/week_view.html:68 +#: templates/alsijil/class_register/week_view.html:242 msgid "Personal notes" msgstr "" -#: models.py:132 templates/alsijil/class_register/week_view.html:64 +#: models.py:137 templates/alsijil/class_register/lesson.html:129 +#: templates/alsijil/class_register/week_view.html:90 +#: templates/alsijil/class_register/week_view.html:177 #: templates/alsijil/print/full_register.html:371 msgid "Lesson topic" msgstr "" -#: models.py:133 templates/alsijil/print/full_register.html:372 +#: models.py:138 templates/alsijil/class_register/lesson.html:137 +#: templates/alsijil/class_register/week_view.html:91 +#: templates/alsijil/class_register/week_view.html:183 +#: templates/alsijil/class_register/week_view.html:216 +#: templates/alsijil/print/full_register.html:372 msgid "Homework" msgstr "" -#: models.py:135 +#: models.py:140 templates/alsijil/class_register/lesson.html:145 +#: templates/alsijil/class_register/week_view.html:92 +#: templates/alsijil/class_register/week_view.html:189 +#: templates/alsijil/class_register/week_view.html:222 msgid "Group note" msgstr "" -#: models.py:178 templates/alsijil/class_register/lesson.html:60 -#: templates/alsijil/class_register/lesson.html:143 +#: models.py:183 templates/alsijil/class_register/lesson.html:97 +#: templates/alsijil/class_register/lesson.html:120 msgid "Lesson documentation" msgstr "" -#: models.py:179 +#: models.py:184 templates/alsijil/class_register/week_view.html:67 msgid "Lesson documentations" msgstr "" -#: models.py:209 +#: models.py:214 msgid "Extra mark" msgstr "" +#: models.py:222 +msgid "Can view week overview" +msgstr "" + +#: models.py:223 +msgid "Can register absence" +msgstr "" + +#: models.py:224 +msgid "Can list all personal note filters" +msgstr "" + #: preferences.py:16 msgid "Block adding personal notes for cancelled lessons" msgstr "" -#: preferences.py:25 +#: preferences.py:24 +msgid "Allow users to view their own personal notes" +msgstr "" + +#: preferences.py:33 +msgid "Allow primary group owners to register future absences for students in their groups" +msgstr "" + +#: preferences.py:43 msgid "Carry over data from first lesson period to the following lesson periods in lessons over multiple periods" msgstr "" -#: preferences.py:28 +#: preferences.py:46 msgid "This will carry over data only if the data in the following periods are empty." msgstr "" -#: preferences.py:38 +#: preferences.py:56 msgid "Allow teachers to open lesson periods on the same day and not just at the beginning of the period" msgstr "" -#: preferences.py:41 +#: preferences.py:59 msgid "Lessons in the past are not affected by this setting, you can open them whenever you want." msgstr "" @@ -201,76 +264,160 @@ msgstr "" msgid "Edit" msgstr "" -#: tables.py:22 tables.py:42 +#: tables.py:22 tables.py:42 templates/alsijil/class_register/person.html:249 msgid "Delete" msgstr "" -#: templates/alsijil/class_register/groups.html:20 +#: templates/alsijil/absences/register.html:5 +#: templates/alsijil/absences/register.html:6 +#: templates/alsijil/class_register/person.html:30 +#: templates/alsijil/class_register/week_view.html:256 +#: templates/alsijil/partials/persons_with_stats.html:115 +msgid "Register absence" +msgstr "" + +#: templates/alsijil/absences/register.html:9 +#: templates/alsijil/class_register/lesson.html:242 +msgid "Person" +msgstr "" + +#: templates/alsijil/class_register/groups.html:21 +msgid "Students" +msgstr "" + +#: templates/alsijil/class_register/groups.html:35 +#: templates/alsijil/class_register/groups.html:69 +#: templates/alsijil/class_register/week_view.html:40 +#: templates/alsijil/class_register/week_view.html:51 +msgid "Students list" +msgstr "" + +#: templates/alsijil/class_register/groups.html:39 +#: templates/alsijil/class_register/groups.html:75 +#: templates/alsijil/class_register/persons.html:27 +#: templates/alsijil/class_register/persons.html:43 +#: templates/alsijil/class_register/students_list.html:16 +#: templates/alsijil/class_register/students_list.html:35 +#: templates/alsijil/class_register/week_view.html:6 +msgid "Week view" +msgstr "" + +#: templates/alsijil/class_register/groups.html:44 +#: templates/alsijil/class_register/groups.html:82 +#: templates/alsijil/class_register/persons.html:31 +#: templates/alsijil/class_register/persons.html:50 +#: templates/alsijil/class_register/students_list.html:20 +#: templates/alsijil/class_register/students_list.html:42 +#: templates/alsijil/class_register/week_view.html:44 +#: templates/alsijil/class_register/week_view.html:58 +msgid "Generate printout" +msgstr "" + +#: templates/alsijil/class_register/groups.html:52 +#: templates/alsijil/class_register/groups.html:88 msgid "No groups available." msgstr "" -#: templates/alsijil/class_register/lesson.html:6 +#: templates/alsijil/class_register/groups.html:64 +msgid "students" +msgstr "" + +#: templates/alsijil/class_register/lesson.html:5 msgid "Lesson" msgstr "" -#: templates/alsijil/class_register/lesson.html:14 -#: templates/alsijil/class_register/lesson.html:83 -#, python-format -msgid "%(period)s. period" +#: templates/alsijil/class_register/lesson.html:20 +msgid "Back to week view" +msgstr "" + +#: templates/alsijil/class_register/lesson.html:29 +msgid "My previous lesson" msgstr "" #: templates/alsijil/class_register/lesson.html:38 -msgid "Previous lesson" +msgid "My next lesson" msgstr "" #: templates/alsijil/class_register/lesson.html:46 -msgid "Next lesson" +#: templates/alsijil/class_register/lesson.html:167 +#, python-format +msgid "%(period)s. period" +msgstr "" + +#: templates/alsijil/class_register/lesson.html:77 +#: templates/alsijil/class_register/lesson.html:359 +#, python-format +msgid "" +"\n" +" Previous %(subject)s lesson\n" +" " +msgstr "" + +#: templates/alsijil/class_register/lesson.html:85 +#: templates/alsijil/class_register/lesson.html:367 +#, python-format +msgid "" +"\n" +" Next %(subject)s lesson\n" +" " +msgstr "" + +#: templates/alsijil/class_register/lesson.html:107 +msgid "Previous lesson" msgstr "" -#: templates/alsijil/class_register/lesson.html:68 -#: templates/alsijil/class_register/lesson.html:249 +#: templates/alsijil/class_register/lesson.html:111 +#: templates/alsijil/class_register/lesson.html:342 msgid "Change history" msgstr "" -#: templates/alsijil/class_register/lesson.html:82 +#: templates/alsijil/class_register/lesson.html:166 msgid "Overview: Previous lesson" msgstr "" -#: templates/alsijil/class_register/lesson.html:89 +#: templates/alsijil/class_register/lesson.html:173 msgid "Lesson topic of previous lesson:" msgstr "" -#: templates/alsijil/class_register/lesson.html:96 +#: templates/alsijil/class_register/lesson.html:180 msgid "Homework for this lesson:" msgstr "" -#: templates/alsijil/class_register/lesson.html:103 +#: templates/alsijil/class_register/lesson.html:187 msgid "Group notes for previous lesson:" msgstr "" -#: templates/alsijil/class_register/lesson.html:110 +#: templates/alsijil/class_register/lesson.html:194 msgid "Absent persons:" msgstr "" -#: templates/alsijil/class_register/lesson.html:117 +#: templates/alsijil/class_register/lesson.html:201 msgid "Late persons:" msgstr "" -#: templates/alsijil/class_register/lesson.html:165 -#: templates/alsijil/class_register/person.html:86 +#: templates/alsijil/class_register/lesson.html:244 +#: templates/alsijil/class_register/person.html:110 +#: templates/alsijil/partials/persons_with_stats.html:17 +#: templates/alsijil/partials/persons_with_stats.html:34 +#: templates/alsijil/partials/persons_with_stats.html:91 #: templates/alsijil/print/full_register.html:287 msgid "Tardiness" msgstr "" -#: templates/alsijil/class_register/lesson.html:188 +#: templates/alsijil/class_register/lesson.html:267 msgid "Tardiness (in m)" msgstr "" -#: templates/alsijil/class_register/person.html:7 +#: templates/alsijil/class_register/person.html:8 msgid "Class register: person" msgstr "" -#: templates/alsijil/class_register/person.html:11 +#: templates/alsijil/class_register/person.html:16 +#: templates/alsijil/class_register/students_list.html:10 +msgid "Back" +msgstr "" + +#: templates/alsijil/class_register/person.html:19 #, python-format msgid "" "\n" @@ -278,118 +425,131 @@ msgid "" " " msgstr "" -#: templates/alsijil/class_register/person.html:19 +#: templates/alsijil/class_register/person.html:36 +#: templates/alsijil/partials/legend.html:14 msgid "Unexcused absences" msgstr "" -#: templates/alsijil/class_register/person.html:27 -#: templates/alsijil/class_register/person.html:44 -#: templates/alsijil/class_register/person.html:160 -#: templates/alsijil/class_register/person.html:202 +#: templates/alsijil/class_register/person.html:46 +#: templates/alsijil/class_register/person.html:65 +#: templates/alsijil/class_register/person.html:190 +#: templates/alsijil/class_register/person.html:237 msgid "Mark as" msgstr "" -#: templates/alsijil/class_register/person.html:30 -#: templates/alsijil/class_register/person.html:47 -#: templates/alsijil/class_register/person.html:163 -#: templates/alsijil/class_register/person.html:205 +#: templates/alsijil/class_register/person.html:49 +#: templates/alsijil/class_register/person.html:68 +#: templates/alsijil/class_register/person.html:193 +#: templates/alsijil/class_register/person.html:199 +#: templates/alsijil/class_register/person.html:240 +#: templates/alsijil/class_register/person.html:246 msgid "Delete note" msgstr "" -#: templates/alsijil/class_register/person.html:55 -msgid "There are unexcused lessons." +#: templates/alsijil/class_register/person.html:78 +msgid "There are no unexcused lessons." msgstr "" -#: templates/alsijil/class_register/person.html:59 +#: templates/alsijil/class_register/person.html:83 msgid "Statistics on absences, tardiness and remarks" msgstr "" -#: templates/alsijil/class_register/person.html:68 +#: templates/alsijil/class_register/person.html:92 +#: templates/alsijil/partials/legend.html:10 +#: templates/alsijil/partials/persons_with_stats.html:16 +#: templates/alsijil/partials/persons_with_stats.html:26 +#: templates/alsijil/partials/persons_with_stats.html:69 #: templates/alsijil/print/full_register.html:269 msgid "Absences" msgstr "" -#: templates/alsijil/class_register/person.html:72 +#: templates/alsijil/class_register/person.html:96 #: templates/alsijil/print/full_register.html:274 msgid "thereof" msgstr "" -#: templates/alsijil/class_register/person.html:82 +#: templates/alsijil/class_register/person.html:106 +#: templates/alsijil/partials/persons_with_stats.html:86 #: templates/alsijil/print/full_register.html:81 #: templates/alsijil/print/full_register.html:283 msgid "Unexcused" msgstr "" -#: templates/alsijil/class_register/person.html:102 +#: templates/alsijil/class_register/person.html:127 #: templates/alsijil/print/full_register.html:304 msgid "Relevant personal notes" msgstr "" -#: templates/alsijil/class_register/person.html:118 +#: templates/alsijil/class_register/person.html:143 #, python-format msgid "Week %(week)s" msgstr "" -#: templates/alsijil/class_register/person.html:126 -#: templates/alsijil/class_register/person.html:135 +#: templates/alsijil/class_register/person.html:152 +#: templates/alsijil/class_register/person.html:163 msgid "Mark all as" msgstr "" -#: templates/alsijil/class_register/person.html:187 +#: templates/alsijil/class_register/person.html:222 #, python-format msgid "%(late)s' late" msgstr "" -#: templates/alsijil/class_register/persons.html:22 -msgid "No students available." -msgstr "" - -#: templates/alsijil/class_register/week_view.html:6 -msgid "Week view" +#: templates/alsijil/class_register/students_list.html:5 +#: templates/alsijil/class_register/students_list.html:12 +#, python-format +msgid "Students list: %(group)s" msgstr "" -#: templates/alsijil/class_register/week_view.html:30 +#: templates/alsijil/class_register/week_view.html:23 msgid "Select" msgstr "" -#: templates/alsijil/class_register/week_view.html:38 +#: templates/alsijil/class_register/week_view.html:31 #, python-format msgid "" "CW %(week)s:\n" " %(instance)s" msgstr "" -#: templates/alsijil/class_register/week_view.html:58 +#: templates/alsijil/class_register/week_view.html:84 msgid "Period" msgstr "" -#: templates/alsijil/class_register/week_view.html:60 +#: templates/alsijil/class_register/week_view.html:86 msgid "Groups" msgstr "" -#: templates/alsijil/class_register/week_view.html:62 +#: templates/alsijil/class_register/week_view.html:88 +#: templates/alsijil/class_register/week_view.html:163 #: templates/alsijil/print/full_register.html:169 #: templates/alsijil/print/full_register.html:200 msgid "Subject" msgstr "" -#: templates/alsijil/class_register/week_view.html:63 +#: templates/alsijil/class_register/week_view.html:89 +#: templates/alsijil/class_register/week_view.html:173 msgid "Teachers" msgstr "" -#: templates/alsijil/class_register/week_view.html:120 +#: templates/alsijil/class_register/week_view.html:262 msgid "unexcused" msgstr "" -#: templates/alsijil/class_register/week_view.html:123 +#: templates/alsijil/class_register/week_view.html:265 msgid "Summed up tardiness" msgstr "" -#: templates/alsijil/class_register/week_view.html:152 +#: templates/alsijil/class_register/week_view.html:268 +#: templates/alsijil/partials/persons_with_stats.html:94 +msgid "Count of tardiness" +msgstr "" + +#: templates/alsijil/class_register/week_view.html:297 msgid "No lessons available" msgstr "" -#: templates/alsijil/class_register/week_view.html:155 +#: templates/alsijil/class_register/week_view.html:300 msgid "" "\n" " There are no lessons for the selected group or teacher in this week.\n" @@ -398,7 +558,7 @@ msgstr "" #: templates/alsijil/excuse_type/create.html:6 #: templates/alsijil/excuse_type/create.html:7 -#: templates/alsijil/excuse_type/list.html:16 +#: templates/alsijil/excuse_type/list.html:18 msgid "Create excuse type" msgstr "" @@ -426,16 +586,33 @@ msgstr "" msgid "Edit extra mark" msgstr "" -#: templates/alsijil/partials/absences.html:4 +#: templates/alsijil/partials/absences.html:6 +#: templates/alsijil/partials/persons_with_stats.html:27 +#: templates/alsijil/partials/persons_with_stats.html:44 #: templates/alsijil/print/full_register.html:126 msgid "(e)" msgstr "" -#: templates/alsijil/partials/absences.html:4 +#: templates/alsijil/partials/absences.html:6 +#: templates/alsijil/partials/persons_with_stats.html:33 +#: templates/alsijil/partials/persons_with_stats.html:50 #: templates/alsijil/print/full_register.html:130 msgid "(u)" msgstr "" +#: templates/alsijil/partials/legend.html:4 +msgid "Legend" +msgstr "" + +#: templates/alsijil/partials/legend.html:7 +#: templates/alsijil/print/full_register.html:71 +msgid "General" +msgstr "" + +#: templates/alsijil/partials/legend.html:18 +msgid "Excused absences" +msgstr "" + #: templates/alsijil/partials/lesson_status_icon.html:6 msgid "Data complete" msgstr "" @@ -464,6 +641,27 @@ msgstr "" msgid "e" msgstr "" +#: templates/alsijil/partials/persons_with_stats.html:7 +msgid "No students available." +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:15 +#: templates/alsijil/partials/persons_with_stats.html:25 +msgid "Primary group" +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:43 +msgid "Sum" +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:107 +msgid "Show more details" +msgstr "" + +#: templates/alsijil/partials/persons_with_stats.html:108 +msgid "Details" +msgstr "" + #: templates/alsijil/print/full_register.html:6 msgid "Class register:" msgstr "" @@ -511,10 +709,6 @@ msgstr "" msgid "Abbreviations" msgstr "" -#: templates/alsijil/print/full_register.html:71 -msgid "General" -msgstr "" - #: templates/alsijil/print/full_register.html:78 msgid "Late" msgstr "" @@ -629,62 +823,58 @@ msgstr "" msgid "Notes" msgstr "" -#: views.py:78 +#: views.py:69 msgid "You either selected an invalid lesson or there is currently no lesson in progress." msgstr "" -#: views.py:96 +#: views.py:95 msgid "You are not allowed to create a lesson documentation for a lesson in the future." msgstr "" -#: views.py:122 +#: views.py:133 msgid "The lesson documentation has been saved." msgstr "" -#: views.py:143 +#: views.py:156 msgid "The personal notes have been saved." msgstr "" -#: views.py:351 -msgid "There is no current school term." -msgstr "" - -#: views.py:532 +#: views.py:587 msgid "The absences have been marked as excused." msgstr "" -#: views.py:548 +#: views.py:605 msgid "The absence has been marked as excused." msgstr "" -#: views.py:653 +#: views.py:735 msgid "The absence has been saved." msgstr "" -#: views.py:670 +#: views.py:754 msgid "The personal note has been deleted." msgstr "" -#: views.py:691 +#: views.py:775 msgid "The extra mark has been created." msgstr "" -#: views.py:702 +#: views.py:786 msgid "The extra mark has been saved." msgstr "" -#: views.py:712 +#: views.py:796 msgid "The extra mark has been deleted." msgstr "" -#: views.py:732 +#: views.py:816 msgid "The excuse type has been created." msgstr "" -#: views.py:743 +#: views.py:827 msgid "The excuse type has been saved." msgstr "" -#: views.py:753 +#: views.py:837 msgid "The excuse type has been deleted." msgstr "" diff --git a/aleksis/apps/alsijil/managers.py b/aleksis/apps/alsijil/managers.py new file mode 100644 index 0000000000000000000000000000000000000000..b2589345adac4c2c02159ea54fc872fe9055408a --- /dev/null +++ b/aleksis/apps/alsijil/managers.py @@ -0,0 +1,23 @@ +from aleksis.core.managers import CurrentSiteManagerWithoutMigrations + + +class PersonalNoteManager(CurrentSiteManagerWithoutMigrations): + """Manager adding specific methods to personal notes.""" + + def get_queryset(self): + """Ensure all related lesson and person data are loaded as well.""" + return ( + super() + .get_queryset() + .select_related( + "person", + "excuse_type", + "lesson_period", + "lesson_period__lesson", + "lesson_period__lesson__subject", + "lesson_period__period", + "lesson_period__lesson__validity", + "lesson_period__lesson__validity__school_term", + ) + .prefetch_related("extra_marks") + ) diff --git a/aleksis/apps/alsijil/menus.py b/aleksis/apps/alsijil/menus.py index 8efb11d58ff0ad01e14d11f262fccc5176065c02..f25429476ba2dfc783ad23a8725877a5b9e20633 100644 --- a/aleksis/apps/alsijil/menus.py +++ b/aleksis/apps/alsijil/menus.py @@ -16,49 +16,78 @@ MENUS = { "name": _("Current lesson"), "url": "lesson", "icon": "alarm", - "validators": ["menu_generator.validators.is_authenticated"], + "validators": [ + ( + "aleksis.core.util.predicates.permission_validator", + "alsijil.view_lesson_menu", + ), + ], }, { "name": _("Current week"), "url": "week_view", "icon": "view_week", - "validators": ["menu_generator.validators.is_authenticated"], + "validators": [ + ( + "aleksis.core.util.predicates.permission_validator", + "alsijil.view_week_menu", + ), + ], }, { "name": _("My groups"), "url": "my_groups", "icon": "people", - "validators": ["menu_generator.validators.is_authenticated"], + "validators": [ + ( + "aleksis.core.util.predicates.permission_validator", + "alsijil.view_my_groups", + ), + ], }, { "name": _("My overview"), "url": "overview_me", "icon": "insert_chart", - "validators": ["menu_generator.validators.is_authenticated"], + "validators": [ + ( + "aleksis.core.util.predicates.permission_validator", + "alsijil.view_person_overview_menu", + ), + ], }, { "name": _("My students"), "url": "my_students", "icon": "people", - "validators": ["menu_generator.validators.is_authenticated"], - }, - { - "name": _("Register absence"), - "url": "register_absence", - "icon": "rate_review", - "validators": ["menu_generator.validators.is_superuser"], + "validators": [ + ( + "aleksis.core.util.predicates.permission_validator", + "alsijil.view_my_students", + ), + ], }, { "name": _("Excuse types"), "url": "excuse_types", "icon": "label", - "validators": ["menu_generator.validators.is_superuser"], + "validators": [ + ( + "aleksis.core.util.predicates.permission_validator", + "alsijil.view_excusetypes", + ), + ], }, { "name": _("Extra marks"), "url": "extra_marks", "icon": "label", - "validators": ["menu_generator.validators.is_superuser"], + "validators": [ + ( + "aleksis.core.util.predicates.permission_validator", + "alsijil.view_extramarks", + ), + ], }, { "name": _("Data checks"), diff --git a/aleksis/apps/alsijil/model_extensions.py b/aleksis/apps/alsijil/model_extensions.py index 0fbfd957568f8a3850642362a0ca755a94e59bbe..0828272f1986f519f5d6b7d748a465b275ed6846 100644 --- a/aleksis/apps/alsijil/model_extensions.py +++ b/aleksis/apps/alsijil/model_extensions.py @@ -1,7 +1,9 @@ from datetime import date -from typing import Dict, Optional, Union +from typing import Dict, Iterable, Iterator, Optional, Union -from django.db.models import Exists, OuterRef, QuerySet +from django.db.models import Exists, OuterRef, Q, QuerySet +from django.db.models.aggregates import Count, Sum +from django.utils.translation import gettext as _ import reversion from calendarweek import CalendarWeek @@ -53,16 +55,20 @@ def mark_absent( continue with reversion.create_revision(): - personal_note, created = PersonalNote.objects.update_or_create( - person=self, - lesson_period=lesson_period, - week=wanted_week.week, - year=wanted_week.year, - defaults={ - "absent": absent, - "excused": excused, - "excuse_type": excuse_type, - }, + personal_note, created = ( + PersonalNote.objects.select_related(None) + .prefetch_related(None) + .update_or_create( + person=self, + lesson_period=lesson_period, + week=wanted_week.week, + year=wanted_week.year, + defaults={ + "absent": absent, + "excused": excused, + "excuse_type": excuse_type, + }, + ) ) personal_note.groups_of_person.set(self.member_of.all()) @@ -75,7 +81,7 @@ def mark_absent( @LessonPeriod.method -def get_personal_notes(self, wanted_week: CalendarWeek): +def get_personal_notes(self, persons: QuerySet, wanted_week: CalendarWeek): """Get all personal notes for that lesson in a specified week. Returns all linked `PersonalNote` objects, filtered by the given weeek, @@ -88,7 +94,7 @@ def get_personal_notes(self, wanted_week: CalendarWeek): - Dominik George <dominik.george@teckids.org> """ # Find all persons in the associated groups that do not yet have a personal note for this lesson - missing_persons = Person.objects.annotate( + missing_persons = persons.annotate( no_personal_notes=~Exists( PersonalNote.objects.filter( week=wanted_week.week, @@ -118,11 +124,51 @@ def get_personal_notes(self, wanted_week: CalendarWeek): for personal_note in new_personal_notes: personal_note.groups_of_person.set(personal_note.person.member_of.all()) - return PersonalNote.objects.select_related("person").filter( - lesson_period=self, week=wanted_week.week, year=wanted_week.year + return ( + PersonalNote.objects.filter( + lesson_period=self, + week=wanted_week.week, + year=wanted_week.year, + person__in=persons, + ) + .select_related(None) + .prefetch_related(None) + .select_related("person", "excuse_type") + .prefetch_related("extra_marks") ) +# Dynamically add extra permissions to Group and Person models in core +# Note: requires migrate afterwards +Group.add_permission( + "view_week_class_register_group", + _("Can view week overview of group class register"), +) +Group.add_permission( + "view_lesson_class_register_group", + _("Can view lesson overview of group class register"), +) +Group.add_permission( + "view_personalnote_group", _("Can view all personal notes of a group") +) +Group.add_permission( + "edit_personalnote_group", _("Can edit all personal notes of a group") +) +Group.add_permission( + "view_lessondocumentation_group", _("Can view all lesson documentation of a group") +) +Group.add_permission( + "edit_lessondocumentation_group", _("Can edit all lesson documentation of a group") +) +Group.add_permission("view_full_register_group", _("Can view full register of a group")) +Group.add_permission( + "register_absence_group", _("Can register an absence for all members of a group") +) +Person.add_permission( + "register_absence_person", _("Can register an absence for a person") +) + + @LessonPeriod.method def get_lesson_documentation( self, week: Optional[CalendarWeek] = None @@ -130,11 +176,14 @@ def get_lesson_documentation( """Get lesson documentation object for this lesson.""" if not week: week = self.week + # Use all to make effect of prefetched data + doc_filter = filter( + lambda d: d.week == week.week and d.year == week.year, + self.documentations.all(), + ) try: - return LessonDocumentation.objects.get( - lesson_period=self, week=week.week, year=week.year - ) - except LessonDocumentation.DoesNotExist: + return next(doc_filter) + except StopIteration: return None @@ -152,11 +201,15 @@ def get_or_create_lesson_documentation( @LessonPeriod.method -def get_absences(self, week: Optional[CalendarWeek] = None) -> QuerySet: +def get_absences(self, week: Optional[CalendarWeek] = None) -> Iterator: """Get all personal notes of absent persons for this lesson.""" if not week: week = self.week - return self.personal_notes.filter(week=week.week, year=week.year, absent=True) + + return filter( + lambda p: p.week == week.week and p.year == week.year and p.absent, + self.personal_notes.all(), + ) @LessonPeriod.method @@ -204,3 +257,136 @@ def get_extra_marks( stats[extra_mark] = qs return stats + + +@Group.class_method +def get_groups_with_lessons(cls: Group): + """Get all groups which have related lessons or child groups with related lessons.""" + group_pks = ( + cls.objects.for_current_school_term_or_all() + .annotate(lessons_count=Count("lessons")) + .filter(lessons_count__gt=0) + .values_list("pk", flat=True) + ) + groups = cls.objects.filter( + Q(child_groups__pk__in=group_pks) | Q(pk__in=group_pks) + ).distinct() + + return groups + + +@Person.method +def get_owner_groups_with_lessons(self: Person): + """Get all groups the person is an owner of and which have related lessons. + + Groups which have child groups with related lessons are also included. + """ + return Group.get_groups_with_lessons().filter(owners=self).distinct() + + +@Group.method +def generate_person_list_with_class_register_statistics( + self: Group, persons: Optional[Iterable] = None +) -> QuerySet: + """Get with class register statistics annotated list of all members.""" + persons = persons or self.members.all() + persons = persons.filter( + personal_notes__groups_of_person=self, + personal_notes__lesson_period__lesson__validity__school_term=self.school_term, + ).annotate( + absences_count=Count( + "personal_notes__absent", + filter=Q( + personal_notes__absent=True, + personal_notes__lesson_period__lesson__validity__school_term=self.school_term, + ) + & ( + Q(personal_notes__lesson_period__lesson__groups=self) + | Q(personal_notes__lesson_period__lesson__groups__parent_groups=self) + ), + ), + excused=Count( + "personal_notes__absent", + filter=Q( + personal_notes__absent=True, + personal_notes__excused=True, + personal_notes__excuse_type__isnull=True, + personal_notes__lesson_period__lesson__validity__school_term=self.school_term, + ) + & ( + Q(personal_notes__lesson_period__lesson__groups=self) + | Q(personal_notes__lesson_period__lesson__groups__parent_groups=self) + ), + ), + unexcused=Count( + "personal_notes__absent", + filter=Q( + personal_notes__absent=True, + personal_notes__excused=False, + personal_notes__lesson_period__lesson__validity__school_term=self.school_term, + ) + & ( + Q(personal_notes__lesson_period__lesson__groups=self) + | Q(personal_notes__lesson_period__lesson__groups__parent_groups=self) + ), + ), + tardiness=Sum( + "personal_notes__late", + filter=( + Q(personal_notes__lesson_period__lesson__groups=self) + | Q(personal_notes__lesson_period__lesson__groups__parent_groups=self) + ), + ), + tardiness_count=Count( + "personal_notes", + filter=~Q(personal_notes__late=0) + & Q( + personal_notes__lesson_period__lesson__validity__school_term=self.school_term, + ) + & ( + Q(personal_notes__lesson_period__lesson__groups=self) + | Q(personal_notes__lesson_period__lesson__groups__parent_groups=self) + ), + ), + ) + + for extra_mark in ExtraMark.objects.all(): + persons = persons.annotate( + **{ + extra_mark.count_label: Count( + "personal_notes", + filter=Q( + personal_notes__extra_marks=extra_mark, + personal_notes__lesson_period__lesson__validity__school_term=self.school_term, + ) + & ( + Q(personal_notes__lesson_period__lesson__groups=self) + | Q( + personal_notes__lesson_period__lesson__groups__parent_groups=self + ) + ), + ) + } + ) + + for excuse_type in ExcuseType.objects.all(): + persons = persons.annotate( + **{ + excuse_type.count_label: Count( + "personal_notes__absent", + filter=Q( + personal_notes__absent=True, + personal_notes__excuse_type=excuse_type, + personal_notes__lesson_period__lesson__validity__school_term=self.school_term, + ) + & ( + Q(personal_notes__lesson_period__lesson__groups=self) + | Q( + personal_notes__lesson_period__lesson__groups__parent_groups=self + ) + ), + ) + } + ) + + return persons diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py index 8f8b6fee054d8fdf136e51a61260bb9725421ec3..cbcb143b3f4c94926b7a6f566be0aa1d95ebef56 100644 --- a/aleksis/apps/alsijil/models.py +++ b/aleksis/apps/alsijil/models.py @@ -3,15 +3,14 @@ from django.contrib.contenttypes.models import ContentType from django.db import models from django.urls import reverse from django.utils.formats import date_format +from django.utils.functional import classproperty from django.utils.translation import gettext_lazy as _ +from cache_memoize import cache_memoize from calendarweek import CalendarWeek -from aleksis.apps.alsijil.data_checks import ( - DATA_CHECKS_BY_NAME, - DATA_CHECKS_CHOICES, - DataCheck, -) +from aleksis.apps.alsijil.data_checks import DATA_CHECKS_BY_NAME, DATA_CHECKS_CHOICES, DataCheck +from aleksis.apps.alsijil.managers import PersonalNoteManager from aleksis.apps.chronos.mixins import WeekRelatedMixin from aleksis.apps.chronos.models import LessonPeriod from aleksis.apps.chronos.util.date import get_current_year @@ -54,6 +53,8 @@ class PersonalNote(ExtensibleModel, WeekRelatedMixin): and remarks about a student in a single lesson period. """ + objects = PersonalNoteManager() + person = models.ForeignKey( "core.Person", models.CASCADE, related_name="personal_notes" ) @@ -251,3 +252,13 @@ class DataCheckResult(ExtensibleModel): class Meta: verbose_name = _("Data check result") verbose_name_plural = _("Data check results") + + +class AlsijilGlobalPermissions(ExtensibleModel): + class Meta: + managed = False + permissions = ( + ("view_week", _("Can view week overview")), + ("register_absence", _("Can register absence")), + ("list_personal_note_filters", _("Can list all personal note filters")), + ) diff --git a/aleksis/apps/alsijil/preferences.py b/aleksis/apps/alsijil/preferences.py index 01dedd9bbe6955226baf3c434f68da557b8557ee..f45441da1705da76e0c196d24c10a66170949e06 100644 --- a/aleksis/apps/alsijil/preferences.py +++ b/aleksis/apps/alsijil/preferences.py @@ -17,6 +17,24 @@ class BlockPersonalNotesForCancelled(BooleanPreference): verbose_name = _("Block adding personal notes for cancelled lessons") +@site_preferences_registry.register +class ViewOwnPersonalNotes(BooleanPreference): + section = alsijil + name = "view_own_personal_notes" + default = True + verbose_name = _("Allow users to view their own personal notes") + + +@site_preferences_registry.register +class RegisterAbsenceAsPrimaryGroupOwner(BooleanPreference): + section = alsijil + name = "register_absence_as_primary_group_owner" + default = True + verbose_name = _( + "Allow primary group owners to register future absences for students in their groups" + ) + + @site_preferences_registry.register class CarryOverDataToNextPeriods(BooleanPreference): section = alsijil diff --git a/aleksis/apps/alsijil/rules.py b/aleksis/apps/alsijil/rules.py new file mode 100644 index 0000000000000000000000000000000000000000..23c22cbe340d1f27af1be11378623817eb360a8b --- /dev/null +++ b/aleksis/apps/alsijil/rules.py @@ -0,0 +1,240 @@ +from rules import add_perm + +from aleksis.core.util.predicates import ( + has_global_perm, + has_object_perm, + has_person, + is_current_person, + is_site_preference_set, +) + +from .util.predicates import ( + has_any_object_absence, + has_lesson_group_object_perm, + has_person_group_object_perm, + has_personal_note_group_perm, + is_group_member, + is_group_owner, + is_lesson_parent_group_owner, + is_lesson_participant, + is_lesson_teacher, + is_none, + is_own_personal_note, + is_person_group_owner, + is_person_primary_group_owner, + is_personal_note_lesson_parent_group_owner, + is_personal_note_lesson_teacher, + is_teacher, +) + +# View lesson +view_lesson_predicate = has_person & ( + is_none # View is opened as "Current lesson" + | is_lesson_teacher + | is_lesson_participant + | is_lesson_parent_group_owner + | has_global_perm("alsijil.view_lesson") + | has_lesson_group_object_perm("core.view_week_class_register_group") +) +add_perm("alsijil.view_lesson", view_lesson_predicate) + +# View lesson in menu +add_perm("alsijil.view_lesson_menu", has_person) + +# View lesson personal notes +view_lesson_personal_notes_predicate = view_lesson_predicate & ( + ~is_lesson_participant + | is_lesson_teacher + | has_global_perm("alsijil.view_personalnote") + | has_lesson_group_object_perm("core.view_personalnote_group") +) +add_perm("alsijil.view_lesson_personalnote", view_lesson_personal_notes_predicate) + +# Edit personal note +edit_lesson_personal_note_predicate = view_lesson_personal_notes_predicate & ( + is_lesson_teacher + | has_global_perm("alsijil.change_personalnote") + | has_lesson_group_object_perm("core.edit_personalnote_group") +) +add_perm("alsijil.edit_lesson_personalnote", edit_lesson_personal_note_predicate) + +# View personal note +view_personal_note_predicate = has_person & ( + ( + is_own_personal_note + & is_site_preference_set("alsijil", "view_own_personal_notes") + ) + | is_personal_note_lesson_teacher + | is_personal_note_lesson_parent_group_owner + | has_global_perm("alsijil.view_personalnote") + | has_personal_note_group_perm("core.view_personalnote_group") +) +add_perm("alsijil.view_personalnote", view_personal_note_predicate) + +# Edit personal note +edit_personal_note_predicate = view_personal_note_predicate & ( + ~is_own_personal_note + | has_global_perm("alsijil.view_personalnote") + | has_personal_note_group_perm("core.edit_personalnote_group") +) +add_perm("alsijil.edit_personalnote", edit_personal_note_predicate) + +# View lesson documentation +view_lesson_documentation_predicate = view_lesson_predicate +add_perm("alsijil.view_lessondocumentation", view_lesson_documentation_predicate) + +# Edit lesson documentation +edit_lesson_documentation_predicate = view_lesson_predicate & ( + is_lesson_teacher + | has_global_perm("alsijil.change_lessondocumentation") + | has_lesson_group_object_perm("core.edit_lessondocumentation_group") +) +add_perm("alsijil.edit_lessondocumentation", edit_lesson_documentation_predicate) + +# View week overview +view_week_predicate = has_person & ( + is_current_person + | is_group_member + | is_group_owner + | has_global_perm("alsijil.view_week") + | has_object_perm("core.view_week_class_register_group") +) +add_perm("alsijil.view_week", view_week_predicate) + +# View week overview in menu +add_perm("alsijil.view_week_menu", has_person) + +# View week personal notes +view_week_personal_notes_predicate = has_person & ( + (is_current_person & is_teacher) + | is_group_owner + | has_global_perm("alsijil.view_personalnote") + | has_object_perm("core.view_personalnote_group") +) +add_perm("alsijil.view_week_personalnote", view_week_personal_notes_predicate) + +# Register absence +register_absence_predicate = has_person & ( + ( + is_person_primary_group_owner + & is_site_preference_set("alsijil", "register_absence_as_primary_group_owner") + ) + | has_global_perm("alsijil.register_absence") + | has_object_perm("core.register_absence_person") + | has_person_group_object_perm("core.register_absence_group") +) +add_perm("alsijil.register_absence", register_absence_predicate) + +# View full register for group +view_full_register_predicate = has_person & ( + is_group_owner + | has_global_perm("alsijil.view_full_register") + | has_object_perm("core.view_full_register_group") +) +add_perm("alsijil.view_full_register", view_full_register_predicate) + +# View students list +view_my_students_predicate = has_person & is_teacher +add_perm("alsijil.view_my_students", view_my_students_predicate) + +# View groups list +view_my_groups_predicate = has_person & is_teacher +add_perm("alsijil.view_my_groups", view_my_groups_predicate) + +# View students list +view_students_list_predicate = view_my_groups_predicate & ( + is_group_owner + | has_global_perm("alsijil.view_personalnote") + | has_object_perm("core.view_personalnote_group") +) +add_perm("alsijil.view_students_list", view_students_list_predicate) + +# View person overview +view_person_overview_predicate = has_person & ( + (is_current_person & is_site_preference_set("alsijil", "view_own_personal_notes")) + | is_person_group_owner +) +add_perm("alsijil.view_person_overview", view_person_overview_predicate) + +# View person overview +view_person_overview_menu_predicate = has_person +add_perm("alsijil.view_person_overview_menu", view_person_overview_menu_predicate) + +# View person overview personal notes +view_person_overview_personal_notes_predicate = view_person_overview_predicate & ( + (is_current_person & is_site_preference_set("alsijil", "view_own_personal_notes")) + | is_person_primary_group_owner + | has_global_perm("alsijil.view_personalnote") + | has_person_group_object_perm("core.view_personalnote_group") +) +add_perm( + "alsijil.view_person_overview_personalnote", + view_person_overview_personal_notes_predicate, +) + +# Edit person overview personal notes +edit_person_overview_personal_notes_predicate = ( + view_person_overview_personal_notes_predicate + & ( + ~is_current_person + | has_global_perm("alsijil.edit_personalnote") + | has_person_group_object_perm("core.edit_personalnote_group") + ) +) +add_perm( + "alsijil.edit_person_overview_personalnote", + edit_person_overview_personal_notes_predicate, +) + +# View person statistics on personal notes +view_person_statistics_personal_notes_predicate = ( + view_person_overview_personal_notes_predicate +) +add_perm( + "alsijil.view_person_statistics_personalnote", + view_person_statistics_personal_notes_predicate, +) + +# View excuse type list +view_excusetypes_predicate = has_person & has_global_perm("alsijil.view_excusetype") +add_perm("alsijil.view_excusetypes", view_excusetypes_predicate) + +# Add excuse type +add_excusetype_predicate = view_excusetypes_predicate & has_global_perm( + "alsijil.add_excusetype" +) +add_perm("alsijil.add_excusetype", add_excusetype_predicate) + +# Edit excuse type +edit_excusetype_predicate = view_excusetypes_predicate & has_global_perm( + "alsijil.change_excusetype" +) +add_perm("alsijil.edit_excusetype", edit_excusetype_predicate) + +# Delete excuse type +delete_excusetype_predicate = view_excusetypes_predicate & has_global_perm( + "alsijil.delete_excusetype" +) +add_perm("alsijil.delete_excusetype", delete_excusetype_predicate) + +# View extra mark list +view_extramarks_predicate = has_person & has_global_perm("alsijil.view_extramark") +add_perm("alsijil.view_extramarks", view_extramarks_predicate) + +# Add extra mark +add_extramark_predicate = view_extramarks_predicate & has_global_perm( + "alsijil.add_extramark" +) +add_perm("alsijil.add_extramark", add_extramark_predicate) + +# Edit extra mark +edit_extramark_predicate = view_extramarks_predicate & has_global_perm( + "alsijil.change_extramark" +) +add_perm("alsijil.edit_extramark", edit_extramark_predicate) + +# Delete extra mark +delete_extramark_predicate = view_extramarks_predicate & has_global_perm( + "alsijil.delete_extramark" +) +add_perm("alsijil.delete_extramark", delete_extramark_predicate) diff --git a/aleksis/apps/alsijil/static/css/alsijil/alsijil.css b/aleksis/apps/alsijil/static/css/alsijil/alsijil.css index e3ca3bf017f0549701a2be7c02f0b6be8a7d3f88..3e14ca014661f0f80d1df639d02949db6ffb59e9 100644 --- a/aleksis/apps/alsijil/static/css/alsijil/alsijil.css +++ b/aleksis/apps/alsijil/static/css/alsijil/alsijil.css @@ -7,3 +7,54 @@ table a.tr-link { width: inherit; height: inherit; } + +.collapsible-icon-right { + align-self: end; + flex-grow: 100; + text-align: right!important; +} + +@media only screen and (min-width: 1201px) { + .hide-on-extra-large-only { + display: none; + } +} + +@media only screen and (max-width: 1200px) { + .show-on-extra-large { + display: none; + } +} + +@media only screen and (max-width: 600px) { + .collection .collection-item.avatar { + padding-left: 20px; + } + .collection .collection-item.avatar:not(.circle-clipper) > .circle { + position: relative; + margin-bottom: 10px; + } +} + +.collapsible li .show-on-active { + display: none; +} + +.collapsible li.active .show-on-active { + display: block; +} + +th.chip-height { + height: 67px; + line-height: 2.2; +} + +.collection-item.chip-height { + height: 52px; + line-height: 2.2; +} + +li.collection-item.button-height { + height: 58px; + line-height: 2.5; +} diff --git a/aleksis/apps/alsijil/static/css/alsijil/lesson.css b/aleksis/apps/alsijil/static/css/alsijil/lesson.css index 6d57c7e9910063dc8dfe359c643e65765cb6ad9c..d402156fc7bc1f750e88a5a9c04bf46fa2fd0d5b 100644 --- a/aleksis/apps/alsijil/static/css/alsijil/lesson.css +++ b/aleksis/apps/alsijil/static/css/alsijil/lesson.css @@ -10,6 +10,11 @@ text-decoration: line-through; } +.alsijil-tardiness-text{ + vertical-align: super; +} + + @media only screen and (max-width : 992px) { table.responsive-table.alsijil-table th, table.responsive-table.alsijil-table td { @@ -17,3 +22,7 @@ vertical-align: top; height: 109px;} } + +.alsijil-top-button { + margin-top: -20px; +} diff --git a/aleksis/apps/alsijil/tables.py b/aleksis/apps/alsijil/tables.py index bd6b47a73f34c5e4343138993ee70162cd19b847..b9a8e68404d6b2672dfbb37d2433e55cad08cf08 100644 --- a/aleksis/apps/alsijil/tables.py +++ b/aleksis/apps/alsijil/tables.py @@ -42,3 +42,9 @@ class ExcuseTypeTable(tables.Table): text=_("Delete"), attrs={"a": {"class": "btn-flat waves-effect waves-red red-text"}}, ) + + def before_render(self, request): + if not request.user.has_perm("alsijil.edit_excusetype"): + self.columns.hide("edit") + if not request.user.has_perm("alsijil.delete_excusetype"): + self.columns.hide("delete") diff --git a/aleksis/apps/alsijil/templates/alsijil/absences/register.html b/aleksis/apps/alsijil/templates/alsijil/absences/register.html index b14890e21438a6e452c4fa3e6c595f99d5b856dd..5452de10e44ca52dd75de373dcb43fe11c29bbf8 100644 --- a/aleksis/apps/alsijil/templates/alsijil/absences/register.html +++ b/aleksis/apps/alsijil/templates/alsijil/absences/register.html @@ -6,6 +6,7 @@ {% block page_title %}{% blocktrans %}Register absence{% endblocktrans %}{% endblock %} {% block content %} + <h6>{% trans "Person" %}: {{ person }}</h6> <form method="post"> {% csrf_token %} @@ -17,7 +18,7 @@ $(document).ready(function () { $("#id_date_start").change(function () { $("#id_date_end").val($("#id_date_start").val()); - $("#id_date_end").change(); + initDatePicker("#id_date_end"); }); }); </script> diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/groups.html b/aleksis/apps/alsijil/templates/alsijil/class_register/groups.html index 87385476b881062b7498a7e2ff35120723bba8bd..a2bf6799df9a4f9390fd1a912d5eb9dab51c3cef 100644 --- a/aleksis/apps/alsijil/templates/alsijil/class_register/groups.html +++ b/aleksis/apps/alsijil/templates/alsijil/class_register/groups.html @@ -1,24 +1,93 @@ {# -*- engine:django -*- #} {% extends "core/base.html" %} -{% load i18n %} +{% load i18n static %} {% block browser_title %}{% blocktrans %}My groups{% endblocktrans %}{% endblock %} - {% block page_title %} {% blocktrans %}My groups{% endblocktrans %} {% endblock %} +{% block extra_head %} + {{ block.super }} + <link rel="stylesheet" href="{% static 'css/alsijil/alsijil.css' %}"/> +{% endblock %} + {% block content %} - <div class="collection"> + <table class="highlight responsive-table hide-on-med-and-down"> + <thead> + <tr> + <th>{% trans "Name" %}</th> + <th>{% trans "Students" %}</th> + <th></th> + </tr> + </thead> {% for group in groups %} - <a class="collection-item" href="{% url "week_view" "group" group.pk %}"> - {{ group }} - </a> + <tr> + <td> + {{ group }} + </td> + <td>{{ group.students_count }}</td> + <td> + <div class="right"> + <a class="btn primary-color waves-effect waves-light" href="{% url "students_list" group.pk %}"> + <i class="material-icons left">people</i> + {% trans "Students list" %} + </a> + <a class="btn secondary-color waves-effect waves-light" href="{% url "week_view" "group" group.pk %}"> + <i class="material-icons left">view_week</i> + {% trans "Week view" %} + </a> + <a class="btn primary waves-effect waves-light" href="{% url "full_register_group" group.pk %}" + target="_blank"> + <i class="material-icons left">print</i> + {% trans "Generate printout" %} + </a> + </div> + </td> + </tr> {% empty %} - <li class="collection-item flow-text"> - {% blocktrans %}No groups available.{% endblocktrans %} - </li> + <tr> + <td class="flow-text" colspan="3"> + {% blocktrans %}No groups available.{% endblocktrans %} + </td> + </tr> {% endfor %} + </table> + + <div class="hide-on-large-only"> + <ul class="collection"> + {% for group in groups %} + <li class="collection-item"> + <span class="title">{{ group }}</span> + <p> + {{ group.students_count }} {% trans "students" %} + </p> + <p> + <a class="btn primary-color waves-effect waves-light" href="{% url "week_view" "group" group.pk %}"> + <i class="material-icons left">people</i> + {% trans "Students list" %} + </a> + </p> + <p> + <a class="btn secondary-color waves-effect waves-light" href="{% url "week_view" "group" group.pk %}"> + <i class="material-icons left">view_week</i> + {% trans "Week view" %} + </a> + </p> + <p> + <a class="btn primary waves-effect waves-light" href="{% url "full_register_group" group.pk %}" + target="_blank"> + <i class="material-icons left">print</i> + {% trans "Generate printout" %} + </a> + </p> + </li> + {% empty %} + <li class="collection-item flow-text"> + {% blocktrans %}No groups available.{% endblocktrans %} + </li> + {% endfor %} + </ul> </div> {% endblock %} diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html b/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html index 9fca5de56fc8bd6316a4db3728ae449cd3882cbb..52462d6947cbee249502a04528f8469dbece41ef 100644 --- a/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html +++ b/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html @@ -1,7 +1,6 @@ {# -*- engine:django -*- #} {% extends "core/base.html" %} -{% load week_helpers material_form_internal %} -{% load material_form i18n static %} +{% load week_helpers material_form_internal material_form i18n static rules time_helpers %} {% block browser_title %}{% blocktrans %}Lesson{% endblocktrans %}{% endblock %} @@ -10,47 +9,85 @@ <link rel="stylesheet" href="{% static 'css/alsijil/lesson.css' %}"/> {% endblock %} -{% block page_title %} - {{ day }}, {% blocktrans with period=lesson_period.period.period %}{{ period }}. period{% endblocktrans %} – +{% block content %} + {% if next_lesson_person or prev_lesson_person %} + <div class="row no-margin"> + <div class="col s12 no-padding"> + {# Back to week view #} + {% with lesson_period.get_lesson_documentation as lesson_doc %} + <a href="{% url "week_view_by_week" lesson_doc.year lesson_doc.week "group" lesson_period.lesson.groups.all.0.pk %}" + class="btn primary-color waves-light waves-effect alsijil-top-button"> + <i class="material-icons left">chevron_left</i> {% trans "Back to week view" %} + </a> + {% endwith %} + + {# Next lesson #} + {% if prev_lesson_person %} + <a class="btn primary waves-effect waves-light alsijil-top-button" + href="{% url "lesson_by_week_and_period" prev_lesson_person.week.year prev_lesson_person.week.week prev_lesson_person.id %}"> + <i class="material-icons left">arrow_back</i> + {% trans "My previous lesson" %} + </a> + {% endif %} - {% for group in lesson_period.get_groups.all %} - <span>{{ group.name }}</span>, - {% endfor %} + {# Previous lesson #} + {% if next_lesson_person %} + <a class="btn primary right waves-effect waves-light alsijil-top-button" + href="{% url "lesson_by_week_and_period" next_lesson_person.week.year next_lesson_person.week.week next_lesson_person.id %}"> + <i class="material-icons right">arrow_forward</i> + {% trans "My next lesson" %} + </a> + {% endif %} + </div> + </div> + {% endif %} - {{ lesson_period.get_subject.name }}, + <h4> + {{ day }}, {% blocktrans with period=lesson_period.period.period %}{{ period }}. period{% endblocktrans %} – - {% for teacher in lesson_period.get_teachers.all %} - {{ teacher.short_name }} - {% endfor %} + {% for group in lesson_period.get_groups.all %} + <span>{{ group.name }}</span>, + {% endfor %} - <span class="right"> + {{ lesson_period.get_subject.name }}, + + {% for teacher in lesson_period.get_teachers.all %} + {{ teacher.short_name }} + {% endfor %} + + <span class="right"> {% include "alsijil/partials/lesson_status_icon.html" with period=lesson_period css_class="medium" %} </span> -{% endblock %} + </h4> + <br/> -{% block content %} - <div class="row"> - <div class="col s12"> - {% with prev_lesson=lesson_period.prev %} - <a class="btn-flat left waves-effect waves-light" - href="{% url "lesson_by_week_and_period" prev_lesson.week.year prev_lesson.week.week prev_lesson.id %}"> - <i class="material-icons left">arrow_back</i> - {% trans "Previous lesson" %} - </a> - {% endwith %} + {% has_perm "alsijil.view_lessondocumentation" user lesson_period as can_view_lesson_documentation %} + {% has_perm "alsijil.edit_lessondocumentation" user lesson_period as can_edit_lesson_documentation %} + {% has_perm "alsijil.edit_lesson_personalnote" user lesson_period as can_edit_lesson_personalnote %} - {% with next_lesson=lesson_period.next %} - <a class="btn-flat right waves-effect waves-light" - href="{% url "lesson_by_week_and_period" next_lesson.week.year next_lesson.week.week next_lesson.id %}"> - <i class="material-icons right">arrow_forward</i> - {% trans "Next lesson" %} - </a> - {% endwith %} - </div> - </div> + <form method="post" class="row"> + <p> + {% if can_edit_lesson_documentation or can_edit_lesson_personalnote %} + {% include "core/partials/save_button.html" %} + {% endif %} + + <a class="btn waves-effect waves-light primary" + href="{% url "lesson_by_week_and_period" prev_lesson.week.year prev_lesson.week.week prev_lesson.id %}"> + <i class="material-icons left">arrow_back</i> + {% blocktrans with subject=lesson_period.get_subject.name %} + Previous {{ subject }} lesson + {% endblocktrans %} + </a> + + <a class="btn right waves-effect waves-light primary" + href="{% url "lesson_by_week_and_period" next_lesson.week.year next_lesson.week.week next_lesson.id %}"> + <i class="material-icons right">arrow_forward</i> + {% blocktrans with subject=lesson_period.get_subject.name %} + Next {{ subject }} lesson + {% endblocktrans %} + </a> + </p> - <form method="post"> - <p>{% include "core/partials/save_button.html" %}</p> {% csrf_token %} <div class="row"> @@ -64,6 +101,12 @@ <a href="#personal-notes">{% trans "Personal notes" %}</a> </li> {% endif %} + {% has_perm "alsijil.view_lessondocumentation" user lesson_period.prev as can_view_prev_lesson_documentation %} + {% if lesson_period.prev.get_lesson_documentation and can_view_prev_lesson_documentation %} + <li class="tab"> + <a href="#previous-lesson">{% trans "Previous lesson" %}</a> + </li> + {% endif %} <li class="tab"> <a href="#version-history">{% trans "Change history" %}</a> </li> @@ -71,11 +114,52 @@ </div> <div class="col s12" id="lesson-documentation"> - {% with prev_lesson=lesson_period.prev prev_doc=prev_lesson.get_lesson_documentation %} - {% with prev_doc=prev_lesson.get_lesson_documentation absences=prev_lesson.get_absences tardinesses=prev_lesson.get_tardinesses extra_marks=prev_lesson.get_extra_marks %} - {% if prev_doc %} - {% weekday_to_date prev_lesson.week prev_lesson.period.weekday as prev_date %} + <div class="card"> + <div class="card-content"> + <span class="card-title"> + {% blocktrans %}Lesson documentation{% endblocktrans %} + </span> + {% if can_edit_lesson_documentation %} + {% form form=lesson_documentation_form %}{% endform %} + {% elif can_view_lesson_documentation %} + <table> + <tr> + <th> + {% trans "Lesson topic" %} + </th> + <td> + {{ lesson_documentation.topic }} + </td> + </tr> + <tr> + <th> + {% trans "Homework" %} + </th> + <td> + {{ lesson_documentation.homework }} + </td> + </tr> + <tr> + <th> + {% trans "Group note" %} + </th> + <td> + {{ lesson_documentation.group_note }} + </td> + </tr> + </table> + {% endif %} + </div> + </div> + </div> + + {% with prev_lesson=lesson_period.prev prev_doc=prev_lesson.get_lesson_documentation %} + {% with absences=prev_lesson.get_absences tardinesses=prev_lesson.get_tardinesses extra_marks=prev_lesson.get_extra_marks %} + {% has_perm "alsijil.view_lessondocumentation" user prev_lesson as can_view_prev_lesson_documentation %} + {% if prev_doc and can_view_prev_lesson_documentation %} + {% weekday_to_date prev_lesson.week prev_lesson.period.weekday as prev_date %} + <div class="col s12" id="previous-lesson"> <div class="card"> <div class="card-content"> <span class="card-title"> @@ -124,7 +208,10 @@ <th>{{ extra_mark.name }}</th> <td> {% for note in notes %} - <span>{{ note.person }}{% if not forloop.last %},{% endif %}</span> + {% has_perm "alsijil.view_personalnote" user note as can_view_personalnote %} + {% if can_view_personalnote %} + <span>{{ note.person }}{% if not forloop.last %},{% endif %}</span> + {% endif %} {% endfor %} </td> </tr> @@ -133,29 +220,21 @@ </table> </div> </div> - {% endif %} - {% endwith %} + </div> + {% endif %} {% endwith %} - - <div class="card"> - <div class="card-content"> - <span class="card-title"> - {% blocktrans %}Lesson documentation{% endblocktrans %} - </span> - - {% form form=lesson_documentation_form %}{% endform %} - </div> - </div> - </div> + {% endwith %} {% if not lesson_period.get_substitution.cancelled or not request.site.preferences.alsijil__block_personal_notes_for_cancelled %} <div class="col s12" id="personal-notes"> <div class="card"> <div class="card-content"> - <span class="card-title"> - {% blocktrans %}Personal notes{% endblocktrans %} - </span> - {% form form=personal_note_formset.management_form %}{% endform %} + <span class="card-title"> + {% blocktrans %}Personal notes{% endblocktrans %} + </span> + {% if can_edit_lesson_personalnote %} + {% form form=personal_note_formset.management_form %}{% endform %} + {% endif %} <table class="striped responsive-table alsijil-table"> <thead> @@ -166,94 +245,129 @@ <th>{% blocktrans %}Excused{% endblocktrans %}</th> <th>{% blocktrans %}Excuse type{% endblocktrans %}</th> <th>{% blocktrans %}Extra marks{% endblocktrans %}</th> - <th>{% blocktrans %}Remarks{% endblocktrans %}</th> </tr> </thead> <tbody> {% for form in personal_note_formset %} - <tr> - {{ form.id }} - <td>{{ form.person_name }}{{ form.person_name.value }}</td> - <td class="center-align"> - <label> - {{ form.absent }} - <span></span> - </label> - </td> - <td> - <div class="input-field"> - {{ form.late }} - <label for="{{ form.absent.id_for_label }}"> - {% trans "Tardiness (in m)" %} + {% if can_edit_lesson_personalnote %} + <tr> + {{ form.id }} + <td>{{ form.person_name }}{{ form.person_name.value }}</td> + <td class="center-align"> + <label> + {{ form.absent }} + <span></span> </label> - </div> - </td> - <td class="center-align"> - <label> - {{ form.excused }} - <span></span> - </label> - </td> - <td> - <div class="input-field"> - {{ form.excuse_type }} - <label for="{{ form.excuse_type.id_for_label }}"> - {% trans "Excuse type" %} + </td> + <td> + <div class="input-field"> + {{ form.late }} + <label for="{{ form.absent.id_for_label }}"> + {% trans "Tardiness (in m)" %} + </label> + </div> + </td> + <td class="center-align"> + <label> + {{ form.excused }} + <span></span> </label> - </div> - </td> - <td> - {% for group, items in form.extra_marks|select_options %} - {% for choice, value, selected in items %} - <label class="{% if selected %} active{% endif %} alsijil-check-box"> - <input type="checkbox" - {% if value == None or value == '' %}disabled{% else %}value="{{ value }}"{% endif %} - {% if selected %} checked="checked"{% endif %} - name="{{ form.extra_marks.html_name }}"> - <span>{{ choice }}</span> + </td> + <td> + <div class="input-field"> + {{ form.excuse_type }} + <label for="{{ form.excuse_type.id_for_label }}"> + {% trans "Excuse type" %} </label> + </div> + </td> + <td> + {% for group, items in form.extra_marks|select_options %} + {% for choice, value, selected in items %} + <label class="{% if selected %} active{% endif %} alsijil-check-box"> + <input type="checkbox" + {% if value == None or value == '' %}disabled{% else %}value="{{ value }}"{% endif %} + {% if selected %} checked="checked"{% endif %} + name="{{ form.extra_marks.html_name }}"> + <span>{{ choice }}</span> + </label> + {% endfor %} {% endfor %} - {% endfor %} - </td> - <td> - <div class="input-field"> - {{ form.remarks }} - <label for="{{ form.absent.id_for_label }}"> - {% trans "Remarks" %} - </label> - </div> - </td> - <td> - <div class="input-field"> - {{ form.remarks }} - <label for="{{ form.absent.id_for_label }}"> - {% trans "Remarks" %} - </label> - </div> - </td> - </tr> + </td> + <td> + <div class="input-field"> + {{ form.remarks }} + <label for="{{ form.absent.id_for_label }}"> + {% trans "Remarks" %} + </label> + </div> + </td> + </tr> + {% else %} + <tr> + <td>{{ form.person_name.value }}</td> + <td><i class="material-icons center">{{ form.absent.value|yesno:"check,clear" }}</i></td> + <td> + <i class="material-icons center">{{ form.late.value|yesno:"check,clear" }}</i> + <span class="alsijil-tardiness-text"> + {% if form.late.value %}{{ form.late.value|to_time|time:"i\m" }}{% endif %} + </span> + </td> + <td><i class="material-icons center">{{ form.excused.value|yesno:"check,clear" }}</i></td> + <td>{% firstof form.excuse_type.value "–" %}</td> + <td> + {% for extra_mark in form.extra_marks.value %} + {{ extra_mark }}{% if not forloop.last %},{% endif %} + {% empty %} + – + {% endfor %} + </td> + <td>{% firstof form.remarks.value "–" %}</td> + </tr> + {% endif %} {% endfor %} </tbody> </table> </div> </div> </div> - {% endif %} - <div class="col s12" id="version-history"> - <div class="card"> - <div class="card-content"> + {% if can_view_lesson_documentation %} + <div class="col s12" id="version-history"> + <div class="card"> + <div class="card-content"> <span class="card-title"> {% blocktrans %}Change history{% endblocktrans %} </span> - {% include 'core/partials/crud_events.html' with obj=lesson_documentation %} + {% include 'core/partials/crud_events.html' with obj=lesson_documentation %} + </div> </div> </div> - </div> + {% endif %} </div> - <p>{% include "core/partials/save_button.html" %}</p> + <p> + {% if can_edit_lesson_documentation or can_edit_lesson_personalnote %} + {% include "core/partials/save_button.html" %} + {% endif %} + + <a class="btn primary waves-effect waves-light" + href="{% url "lesson_by_week_and_period" prev_lesson.week.year prev_lesson.week.week prev_lesson.id %}"> + <i class="material-icons left">arrow_back</i> + {% blocktrans with subject=lesson_period.get_subject.name %} + Previous {{ subject }} lesson + {% endblocktrans %} + </a> + + <a class="btn primary right waves-effect waves-light" + href="{% url "lesson_by_week_and_period" next_lesson.week.year next_lesson.week.week next_lesson.id %}"> + <i class="material-icons right">arrow_forward</i> + {% blocktrans with subject=lesson_period.get_subject.name %} + Next {{ subject }} lesson + {% endblocktrans %} + </a> + </p> </form> {% endblock %} diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/person.html b/aleksis/apps/alsijil/templates/alsijil/class_register/person.html index dd907383585e258879539a07508a5e9c0aae7b81..826d5b8fe8a5d5159adb996e6bc0f46e2dce0d9a 100644 --- a/aleksis/apps/alsijil/templates/alsijil/class_register/person.html +++ b/aleksis/apps/alsijil/templates/alsijil/class_register/person.html @@ -1,5 +1,6 @@ {# -*- engine:django -*- #} {% extends "core/base.html" %} +{% load rules %} {% load data_helpers %} {% load week_helpers %} {% load i18n %} @@ -8,12 +9,28 @@ {% block page_title %} + {% has_perm "alsijil.view_my_students" user as has_students %} + {% if has_students %} + <a href="{% url "my_students" %}" + class="btn-flat primary-color-text waves-light waves-effect"> + <i class="material-icons left">chevron_left</i> {% trans "Back" %} + </a> + {% endif %} {% blocktrans with person=person %} Class register overview for {{ person }} {% endblocktrans %} {% endblock %} {% block content %} + {% has_perm "alsijil.edit_person_overview_personalnote" user person as can_mark_all_as_excused %} + {% has_perm "alsijil.register_absence" user person as can_register_absence %} + {% if can_register_absence %} + <a class="btn primary-color waves-effect waves-light" href="{% url "register_absence" person.pk %}"> + <i class="material-icons left">rate_review</i> + {% trans "Register absence" %} + </a> + {% endif %} + <div class="row"> <div class="col s12 m12 l6"> <h5>{% trans "Unexcused absences" %}</h5> @@ -22,16 +39,19 @@ {% for note in unexcused_absences %} {% weekday_to_date note.calendar_week note.lesson_period.period.weekday as note_date %} <li class="collection-item"> - <form action="" method="post" class="right hide-on-small-only" style="margin-top: -7px;"> - {% csrf_token %} - {% trans "Mark as" %} - <input type="hidden" value="{{ note.pk }}" name="personal_note"> - {% include "alsijil/partials/mark_as_buttons.html" %} - <a class="btn-flat red-text" title="{% trans "Delete note" %}" - href="{% url "delete_personal_note" note.pk %}"> - <i class="material-icons center">cancel</i> - </a> - </form> + {% has_perm "alsijil.edit_personalnote" user note as can_edit_personal_note %} + {% if can_edit_personal_note %} + <form action="" method="post" class="right hide-on-small-only" style="margin-top: -7px;"> + {% csrf_token %} + {% trans "Mark as" %} + <input type="hidden" value="{{ note.pk }}" name="personal_note"> + {% include "alsijil/partials/mark_as_buttons.html" %} + <a class="btn-flat red-text" title="{% trans "Delete note" %}" + href="{% url "delete_personal_note" note.pk %}"> + <i class="material-icons center">cancel</i> + </a> + </form> + {% endif %} <i class="material-icons left red-text">warning</i> <p class="no-margin"> <a href="{% url "lesson_by_week_and_period" note.year note.week note.lesson_period.pk %}">{{ note_date }}, {{ note.lesson_period }}</a> @@ -39,64 +59,69 @@ {% if note.remarks %} <p class="no-margin"><em>{{ note.remarks }}</em></p> {% endif %} - <form action="" method="post" class="hide-on-med-and-up"> - {% csrf_token %} - {% trans "Mark as" %} - <input type="hidden" value="{{ note.pk }}" name="personal_note"> - {% include "alsijil/partials/mark_as_buttons.html" %} - <a class="btn-flat red-text" title="{% trans "Delete note" %}" - href="{% url "delete_personal_note" note.pk %}"> - <i class="material-icons center">cancel</i> - </a> - </form> + {% if can_edit_personal_note %} + <form action="" method="post" class="hide-on-med-and-up"> + {% csrf_token %} + {% trans "Mark as" %} + <input type="hidden" value="{{ note.pk }}" name="personal_note"> + {% include "alsijil/partials/mark_as_buttons.html" %} + <a class="btn-flat red-text" title="{% trans "Delete note" %}" + href="{% url "delete_personal_note" note.pk %}"> + <i class="material-icons center">cancel</i> + </a> + </form> + {% endif %} </li> {% empty %} - <li class="collection-item flow-text"> - {% trans "There are unexcused lessons." %} + <li class="collection-item avatar valign-wrapper"> + <i class="material-icons left circle green white-text">check</i> + <span class="title">{% trans "There are no unexcused lessons." %}</span> </li> {% endfor %} </ul> - <h5>{% trans "Statistics on absences, tardiness and remarks" %}</h5> - <ul class="collapsible"> - {% for school_term, stat in stats %} - <li {% if forloop.first %}class="active"{% endif %}> - <div class="collapsible-header"> - <i class="material-icons">date_range</i>{{ school_term }}</div> - <div class="collapsible-body"> - <table> - <tr> - <th colspan="2">{% trans 'Absences' %}</th> - <td>{{ stat.absences_count }}</td> - </tr> - <tr> - <td rowspan="{{ excuse_types.count|add:2 }}" class="hide-on-small-only">{% trans "thereof" %}</td> - <td rowspan="{{ excuse_types.count|add:2 }}" class="hide-on-med-and-up"></td> - <th class="truncate">{% trans 'Excused' %}</th> - <td>{{ stat.excused }}</td> - </tr> - {% for excuse_type in excuse_types %} - <th>{{ excuse_type.name }}</th> - <td>{{ stat|get_dict:excuse_type.count_label }}</td> - {% endfor %} - <tr> - <th>{% trans 'Unexcused' %}</th> - <td>{{ stat.unexcused }}</td> - </tr> - <tr> - <th colspan="2">{% trans 'Tardiness' %}</th> - <td>{{ stat.tardiness }}'</td> - </tr> - {% for extra_mark in extra_marks %} + {% if stats %} + <h5>{% trans "Statistics on absences, tardiness and remarks" %}</h5> + <ul class="collapsible"> + {% for school_term, stat in stats %} + <li {% if forloop.first %}class="active"{% endif %}> + <div class="collapsible-header"> + <i class="material-icons">date_range</i>{{ school_term }}</div> + <div class="collapsible-body"> + <table> <tr> - <th colspan="2">{{ extra_mark.name }}</th> - <td>{{ stat|get_dict:extra_mark.count_label }}</td> + <th colspan="2">{% trans 'Absences' %}</th> + <td>{{ stat.absences_count }}</td> </tr> - {% endfor %} - </table> - </div> - </li> - {% endfor %} - </ul> + <tr> + <td rowspan="{{ excuse_types.count|add:2 }}" class="hide-on-small-only">{% trans "thereof" %}</td> + <td rowspan="{{ excuse_types.count|add:2 }}" class="hide-on-med-and-up"></td> + <th class="truncate">{% trans 'Excused' %}</th> + <td>{{ stat.excused }}</td> + </tr> + {% for excuse_type in excuse_types %} + <th>{{ excuse_type.name }}</th> + <td>{{ stat|get_dict:excuse_type.count_label }}</td> + {% endfor %} + <tr> + <th>{% trans 'Unexcused' %}</th> + <td>{{ stat.unexcused }}</td> + </tr> + <tr> + <th colspan="2">{% trans 'Tardiness' %}</th> + <td>{{ stat.tardiness }}'/{{ stat.tardiness_count }} ×</td> + </tr> + {% for extra_mark in extra_marks %} + <tr> + <th colspan="2">{{ extra_mark.name }}</th> + <td>{{ stat|get_dict:extra_mark.count_label }}</td> + </tr> + {% endfor %} + </table> + </div> + </li> + {% endfor %} + </ul> + {% endif %} </div> <div class="col s12 m12 l6"> <h5>{% trans "Relevant personal notes" %}</h5> @@ -121,21 +146,25 @@ {% weekday_to_date note.calendar_week note.lesson_period.period.weekday as note_date %} {% ifchanged note_date %} <li class="collection-item"> - <form action="" method="post" class="right hide-on-small-only" style="margin-top: -7px;"> - {% csrf_token %} - {% trans "Mark all as" %} - <input type="hidden" value="{{ note_date|date:"Y-m-d" }}" name="date"> - {% include "alsijil/partials/mark_as_buttons.html" %} - </form> + {% if can_mark_all_as_excused %} + <form action="" method="post" class="right hide-on-small-only" style="margin-top: -7px;"> + {% csrf_token %} + {% trans "Mark all as" %} + <input type="hidden" value="{{ note_date|date:"Y-m-d" }}" name="date"> + {% include "alsijil/partials/mark_as_buttons.html" %} + </form> + {% endif %} <i class="material-icons left">schedule</i> {{ note_date }} - <form action="" method="post" class="hide-on-med-and-up"> - {% csrf_token %} - {% trans "Mark all as" %} - <input type="hidden" value="{{ note_date|date:"Y-m-d" }}" name="date"> - {% include "alsijil/partials/mark_as_buttons.html" %} - </form> + {% if can_mark_all_as_excused %} + <form action="" method="post" class="hide-on-med-and-up"> + {% csrf_token %} + {% trans "Mark all as" %} + <input type="hidden" value="{{ note_date|date:"Y-m-d" }}" name="date"> + {% include "alsijil/partials/mark_as_buttons.html" %} + </form> + {% endif %} </li> {% endifchanged %} @@ -154,7 +183,8 @@ </div> <div class="col s12 m7 no-padding"> - {% if note.absent and not note.excused %} + {% has_perm "alsijil.edit_personalnote" user note as can_edit_personal_note %} + {% if note.absent and not note.excused and can_edit_personal_note %} <form action="" method="post" class="right hide-on-small-only" style="margin-top: -7px;"> {% csrf_token %} {% trans "Mark as" %} @@ -165,6 +195,11 @@ <i class="material-icons center">cancel</i> </a> </form> + {% elif can_edit_personal_note %} + <a class="btn-flat red-text right hide-on-small-only" title="{% trans "Delete note" %}" + href="{% url "delete_personal_note" note.pk %}"> + <i class="material-icons center">cancel</i> + </a> {% endif %} {% if note.absent %} @@ -196,7 +231,7 @@ </div> <div class="col s12 hide-on-med-and-up"> - {% if note.absent and not note.excused %} + {% if note.absent and not note.excused and can_edit_personal_note %} <form action="" method="post"> {% csrf_token %} {% trans "Mark as" %} @@ -207,6 +242,12 @@ <i class="material-icons center">cancel</i> </a> </form> + {% elif can_edit_personal_note %} + <a class="btn-flat red-text" title="{% trans "Delete note" %}" + href="{% url "delete_personal_note" note.pk %}"> + <i class="material-icons left">cancel</i> + {% trans "Delete" %} + </a> {% endif %} </div> </li> diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/persons.html b/aleksis/apps/alsijil/templates/alsijil/class_register/persons.html index c3f5e35d48991bafd37ffdc3def7f445d1400247..84461c1830f81c411607f914c5102339dc62c709 100644 --- a/aleksis/apps/alsijil/templates/alsijil/class_register/persons.html +++ b/aleksis/apps/alsijil/templates/alsijil/class_register/persons.html @@ -1,8 +1,6 @@ {# -*- engine:django -*- #} {% extends "core/base.html" %} -{% load data_helpers %} -{% load week_helpers %} -{% load i18n %} +{% load i18n week_helpers data_helpers static time_helpers %} {% block browser_title %}{% blocktrans %}My students{% endblocktrans %}{% endblock %} @@ -11,16 +9,56 @@ {% blocktrans %}My students{% endblocktrans %} {% endblock %} +{% block extra_head %} + {{ block.super }} + <link rel="stylesheet" href="{% static 'css/alsijil/alsijil.css' %}"/> +{% endblock %} + + {% block content %} - <div class="collection"> - {% for person in persons %} - <a class="collection-item" href="{% url "overview_person" person.pk %}"> - {{ person }} - </a> - {% empty %} - <li class="collection-item flow-text"> - {% blocktrans %}No students available.{% endblocktrans %} + <ul class="collapsible"> + {% for group, persons in groups %} + <li {% if forloop.first %}class="active"{% endif %}> + <div class="collapsible-header"> + <div class="hundred-percent"> + <span class="right show-on-active hide-on-small-and-down"> + <a class="btn primary-color waves-effect waves-light" href="{% url "week_view" "group" group.pk %}"> + <i class="material-icons left">view_week</i> + {% trans "Week view" %} + </a> + <a class="btn waves-effect waves-light" href="{% url "full_register_group" group.pk %}" target="_blank"> + <i class="material-icons left">print</i> + {% trans "Generate printout" %} + </a> + </span> + + <h6>{{ group.name }} + <span class="chip">{{ group.school_term }}</span> + </h6> + + <p class="show-on-active hide-on-med-and-up"> + <a class="btn primary-color waves-effect waves-light hundred-percent" + href="{% url "week_view" "group" group.pk %}"> + <i class="material-icons left">view_week</i> + {% trans "Week view" %} + </a> + </p> + <p class="show-on-active hide-on-med-and-up"> + <a class="btn waves-effect waves-light hundred-percent" href="{% url "full_register_group" group.pk %}" + target="_blank"> + <i class="material-icons left">print</i> + {% trans "Generate printout" %} + </a> + </p> + </div> + </div> + + <div class="collapsible-body"> + {% include "alsijil/partials/persons_with_stats.html" with persons=persons %} + </div> </li> {% endfor %} - </div> + </ul> + + {% include "alsijil/partials/legend.html" %} {% endblock %} diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html b/aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html new file mode 100644 index 0000000000000000000000000000000000000000..245addc839dfb2991eb535b46017aa5866def7d2 --- /dev/null +++ b/aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html @@ -0,0 +1,49 @@ +{# -*- engine:django -*- #} +{% extends "core/base.html" %} +{% load static time_helpers data_helpers week_helpers i18n %} + +{% block browser_title %}{% blocktrans with group=group %}Students list: {{ group }}{% endblocktrans %}{% endblock %} + +{% block page_title %} + <a href="{% url "my_groups" %}" + class="btn-flat primary-color-text waves-light waves-effect"> + <i class="material-icons left">chevron_left</i> {% trans "Back" %} + </a> + {% blocktrans with group=group %}Students list: {{ group }}{% endblocktrans %} + <span class="right show-on-active hide-on-small-and-down"> + <a class="btn primary-color waves-effect waves-light" href="{% url "week_view" "group" group.pk %}"> + <i class="material-icons left">view_week</i> + {% trans "Week view" %} + </a> + <a class="btn waves-effect waves-light" href="{% url "full_register_group" group.pk %}" target="_blank"> + <i class="material-icons left">print</i> + {% trans "Generate printout" %} + </a> + </span> +{% endblock %} + +{% block extra_head %} + {{ block.super }} + <link rel="stylesheet" href="{% static 'css/alsijil/alsijil.css' %}"/> +{% endblock %} + +{% block content %} + <p class="show-on-active hide-on-med-and-up"> + <a class="btn primary-color waves-effect waves-light hundred-percent" + href="{% url "week_view" "group" group.pk %}"> + <i class="material-icons left">view_week</i> + {% trans "Week view" %} + </a> + </p> + <p class="show-on-active hide-on-med-and-up"> + <a class="btn waves-effect waves-light hundred-percent" href="{% url "full_register_group" group.pk %}" + target="_blank"> + <i class="material-icons left">print</i> + {% trans "Generate printout" %} + </a> + </p> + + {% include "alsijil/partials/persons_with_stats.html" with persons=persons %} + + {% include "alsijil/partials/legend.html" %} +{% endblock %} diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html b/aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html index ea549f7f15783769f79a9d598304b856481adb18..ac9cee7584efcf65263f78ea8a8cdf1933aa6f7d 100644 --- a/aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html +++ b/aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html @@ -1,7 +1,7 @@ {# -*- engine:django -*- #} {% extends "core/base.html" %} -{% load material_form i18n week_helpers static data_helpers %} +{% load material_form i18n week_helpers static data_helpers rules time_helpers %} {% block browser_title %}{% blocktrans %}Week view{% endblocktrans %}{% endblock %} @@ -15,14 +15,7 @@ {{ week_select|json_script:"week_select" }} <script type="text/javascript" src="{% static "js/chronos/week_select.js" %}"></script> <div class="row"> - {% if group %} - <div class="col s12 m2 push-m10 l1 push-l11"> - <a class="col s12 btn waves-effect waves-light right" href="{% url 'full_register_group' group.id %}"> - <i class="material-icons center">print</i> - </a> - </div> - {% endif %} - <div class="col s12 {% if group %}m10 pull-m2 l11 pull-l1 {% endif %}"> + <div class="col s12"> <form method="post" action=""> {% csrf_token %} {% form form=select_form %}{% endform %} @@ -34,18 +27,51 @@ </div> - <div class="row"> + <div class="row no-margin"> <h4 class="col s12 m6">{% blocktrans with el=el week=week.week %}CW {{ week }}: {{ instance }}{% endblocktrans %} </h4> {% include "chronos/partials/week_select.html" with wanted_week=week %} </div> + {% if group %} + <p class="hide-on-med-and-down"> + <a class="btn primary-color waves-effect waves-light" href="{% url "students_list" group.pk %}"> + <i class="material-icons left">people</i> + {% trans "Students list" %} + </a> + <a class="btn waves-effect waves-light" href="{% url "full_register_group" group.pk %}" target="_blank"> + <i class="material-icons left">print</i> + {% trans "Generate printout" %} + </a> + </p> + + <p class="hide-on-med-and-up"> + <a class="btn primary-color waves-effect waves-light hundred-percent" href="{% url "students_list" group.pk %}"> + <i class="material-icons left">people</i> + {% trans "Students list" %} + </a> + </p> + <p class="hide-on-med-and-up"> + <a class="btn waves-effect waves-light hundred-percent" href="{% url "full_register_group" group.pk %}" + target="_blank"> + <i class="material-icons left">print</i> + {% trans "Generate printout" %} + </a> + </p> + {% endif %} + {% if lesson_periods %} <div class="row"> - <div class="col s12 m7"> + <div class="col s12"> + <ul class="tabs"> + <li class="tab col s6"><a class="active" href="#week-overview">{% trans "Lesson documentations" %}</a></li> + <li class="tab col s6"><a class="active" href="#personal-notes">{% trans "Personal notes" %}</a></li> + </ul> + </div> + <div class="col s12" id="week-overview"> {% regroup lesson_periods by period.get_weekday_display as periods_by_day %} {% for weekday, periods in periods_by_day %} - <div class="card"> + <div class="card show-on-extra-large"> <div class="card-content"> {% weekday_to_date week periods.0.period.weekday as current_date %} <span class="card-title"> @@ -62,50 +88,154 @@ <th>{% blocktrans %}Subject{% endblocktrans %}</th> <th>{% blocktrans %}Teachers{% endblocktrans %}</th> <th>{% blocktrans %}Lesson topic{% endblocktrans %}</th> + <th>{% blocktrans %}Homework{% endblocktrans %}</th> + <th>{% blocktrans %}Group note{% endblocktrans %}</th> </tr> </thead> <tbody> {% for period in periods %} - <tr> - <td class="center-align"> - {% include "alsijil/partials/lesson_status_icon.html" with period=period %} - </td> - <td class="tr-link"> - <a class="tr-link" href="{% url 'lesson_by_week_and_period' week.year week.week period.id %}"> - {{ period.period.period }}. - </a> - </td> - {% if not group %} + {% has_perm "alsijil.view_lessondocumentation" user period as can_view_lesson_documentation %} + {% if can_view_lesson_documentation %} + <tr> + <td class="center-align"> + {% include "alsijil/partials/lesson_status_icon.html" with period=period %} + </td> + <td class="tr-link"> + <a class="tr-link" href="{% url 'lesson_by_week_and_period' week.year week.week period.id %}"> + {{ period.period.period }}. + </a> + </td> + {% if not group %} + <td> + <a class="tr-link" href="{% url 'lesson_by_week_and_period' week.year week.week period.id %}"> + {{ period.lesson.group_names }} + </a> + </td> + {% endif %} <td> <a class="tr-link" href="{% url 'lesson_by_week_and_period' week.year week.week period.id %}"> - {{ period.lesson.group_names }} + {{ period.get_subject.name }} </a> </td> - {% endif %} - <td> - <a class="tr-link" href="{% url 'lesson_by_week_and_period' week.year week.week period.id %}"> - {{ period.get_subject.name }} - </a> - </td> - <td> - <a class="tr-link" href="{% url 'lesson_by_week_and_period' week.year week.week period.id %}"> - {{ period.get_teacher_names }} - </a> - </td> - <td> - <a class="tr-link" href="{% url 'lesson_by_week_and_period' week.year week.week period.id %}"> - {{ period.get_lesson_documentation.topic }} - </a> - </td> - </tr> + <td> + <a class="tr-link" href="{% url 'lesson_by_week_and_period' week.year week.week period.id %}"> + {{ period.get_teacher_names }} + </a> + </td> + <td> + <a class="tr-link" href="{% url 'lesson_by_week_and_period' week.year week.week period.id %}"> + {% firstof period.get_lesson_documentation.topic "–" %} + </a> + </td> + <td> + <a class="tr-link" href="{% url 'lesson_by_week_and_period' week.year week.week period.id %}"> + {% firstof period.get_lesson_documentation.homework "–" %} + </a> + </td> + <td> + <a class="tr-link" href="{% url 'lesson_by_week_and_period' week.year week.week period.id %}"> + {% firstof period.get_lesson_documentation.group_note "–" %} + </a> + </td> + </tr> + {% endif %} {% endfor %} </tbody> </table> </div> </div> + <ul class="collapsible hide-on-extra-large-only"> + <li class=""> + {% weekday_to_date week periods.0.period.weekday as current_date %} + <div class="collapsible-header flow-text"> + {{ weekday }}, {{ current_date }} <i class="material-icons collapsible-icon-right">expand_more</i> + </div> + <div class="collapsible-body"> + <div class="collection"> + {% for period in periods %} + {% has_perm "alsijil.view_lessondocumentation" user period as can_view_lesson_documentation %} + {% if can_view_lesson_documentation %} + <a class="collection-item avatar" + href="{% url 'lesson_by_week_and_period' week.year week.week period.id %}"> + {% include "alsijil/partials/lesson_status_icon.html" with period=period css_class="circle" color_suffix=" " %} + <table class="hide-on-med-and-down"> + <tr> + <th>{% trans "Subject" %}</th> + <td>{{ period.period.period }}. {{ period.get_subject.name }}</td> + </tr> + {% if not group %} + <tr> + <th>{% trans "Group" %}</th> + <td>{{ period.lesson.group_names }}</td> + </tr> + {% endif %} + <tr> + <th>{% trans "Teachers" %}</th> + <td>{{ period.lesson.teacher_names }}</td> + </tr> + <tr> + <th>{% trans "Lesson topic" %}</th> + <td>{% firstof period.get_lesson_documentation.topic "–" %}</td> + </tr> + {% with period.get_lesson_documentation as lesson_documentation %} + {% if lesson_documentation.homework %} + <tr> + <th>{% trans "Homework" %}</th> + <td>{% firstof period.get_lesson_documentation.homework "–" %}</td> + </tr> + {% endif %} + {% if lesson_documentation.group_note %} + <tr> + <th>{% trans "Group note" %}</th> + <td>{% firstof period.get_lesson_documentation.group_note "–" %}</td> + </tr> + {% endif %} + {% endwith %} + </table> + <div class="hide-on-large-only"> + <ul class="collection"> + <li class="collection-item"> + {{ period.period.period }}. {{ period.get_subject.name }} + </li> + {% if not group %} + <li class="collection-item"> + + {{ period.lesson.group_names }} + + </li> + {% endif %} + <li class="collection-item"> + {{ period.lesson.teacher_names }} + </li> + <li class="collection-item"> + {{ period.get_lesson_documentation.topic }} + </li> + {% with period.get_lesson_documentation as lesson_documentation %} + {% if lesson_documentation.homework %} + <li class="collection-item"> + <strong>{% trans "Homework" %}</strong> + {% firstof period.get_lesson_documentation.homework "–" %} + </li> + {% endif %} + {% if lesson_documentation.group_note %} + <li class="collection-item"> + <strong>{% trans "Group note" %}</strong> + {% firstof period.get_lesson_documentation.group_note "–" %} + </li> + {% endif %} + {% endwith %} + </ul> + </div> + </a> + {% endif %} + {% endfor %} + </div> + </div> + </li> + </ul> {% endfor %} </div> - <div class="col s12 m5"> + <div class="col s12" id="personal-notes"> <div class="card"> <div class="card-content"> <span class="card-title"> @@ -113,14 +243,29 @@ </span> {% for person in persons %} <h5 class="card-title"> - <a href="{% url "overview_person" person.person.pk %}">{{ person.person.full_name }}</a> + {% has_perm "alsijil.view_person_overview" user person.person as can_view_person_overview %} + {% if can_view_person_overview %} + <a href="{% url "overview_person" person.person.pk %}">{{ person.person.full_name }}</a> + {% else %} + {{ person.person.full_name }} + {% endif %} + {% has_perm "alsijil.register_absence" user person.person as can_register_absence %} + {% if can_register_absence %} + <a class="btn primary-color waves-effect waves-light right" href="{% url "register_absence" person.person.pk %}"> + <i class="material-icons left">rate_review</i> + {% trans "Register absence" %} + </a> + {% endif %} </h5> <p class="card-text"> {% trans "Absent" %}: {{ person.person.absences_count }} ({{ person.person.unexcused_count }} {% trans "unexcused" %}) </p> <p class="card-text"> - {% trans "Summed up tardiness" %}: {{ person.person.tardiness_sum }}' + {% trans "Summed up tardiness" %}: {% firstof person.person.tardiness_sum|to_time|time:"H\h i\m" "–" %} + </p> + <p class="card-text"> + {% trans "Count of tardiness" %}: {{ person.person.tardiness_count }} × </p> {% for extra_mark in extra_marks %} <p class="card-text"> diff --git a/aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html b/aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html index 2be1f28c96e70f35e63fe4f5cefb50c232e38e0a..9c74d62e127f6a03b1ad7637114badfc2f4d9de2 100644 --- a/aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html +++ b/aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html @@ -2,7 +2,7 @@ {% extends "core/base.html" %} -{% load i18n %} +{% load i18n rules %} {% load render_table from django_tables2 %} {% block browser_title %}{% blocktrans %}Excuse types{% endblocktrans %}{% endblock %} @@ -11,10 +11,13 @@ {% block content %} {% include "alsijil/excuse_type/warning.html" %} - <a class="btn green waves-effect waves-light" href="{% url 'create_excuse_type' %}"> - <i class="material-icons left">add</i> - {% trans "Create excuse type" %} - </a> + {% has_perm "alsijil.add_excusetype" user as add_excusetype %} + {% if add_excusetype %} + <a class="btn green waves-effect waves-light" href="{% url 'create_excuse_type' %}"> + <i class="material-icons left">add</i> + {% trans "Create excuse type" %} + </a> + {% endif %} {% render_table table %} {% endblock %} diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/absences.html b/aleksis/apps/alsijil/templates/alsijil/partials/absences.html index 6deaa3891c480026b22fbad2cfc75a4f2b260110..c72204c556efee0c5308d607947b5cd9670d85c3 100644 --- a/aleksis/apps/alsijil/templates/alsijil/partials/absences.html +++ b/aleksis/apps/alsijil/templates/alsijil/partials/absences.html @@ -1,6 +1,9 @@ -{% load i18n %} +{% load i18n rules %} {% for note in notes %} - <span class="{% if note.excused %}green-text{% else %}red-text{% endif %}">{{ note.person }} - {% if note.excused %}{% if note.excuse_type %}({{ note.excuse_type.short_name }}){% else %}{% trans "(e)" %}{% endif %}{% else %}{% trans "(u)" %}{% endif %}{% if not forloop.last %},{% endif %} - </span> + {% has_perm "alsijil.view_personalnote" user note as can_view_personalnote %} + {% if can_view_personalnote %} + <span class="{% if note.excused %}green-text{% else %}red-text{% endif %}">{{ note.person }} + {% if note.excused %}{% if note.excuse_type %}({{ note.excuse_type.short_name }}){% else %}{% trans "(e)" %}{% endif %}{% else %}{% trans "(u)" %}{% endif %}{% if not forloop.last %},{% endif %} + </span> + {% endif %} {% endfor %} diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/legend.html b/aleksis/apps/alsijil/templates/alsijil/partials/legend.html new file mode 100644 index 0000000000000000000000000000000000000000..a2c6ba1aaee02c492155c08b902f1562b405b3a7 --- /dev/null +++ b/aleksis/apps/alsijil/templates/alsijil/partials/legend.html @@ -0,0 +1,55 @@ +{% load i18n %} +<div class="card"> + <div class="card-content"> + <div class="card-title">{% trans "Legend" %}</div> + <div class="row"> + <div class="col s12 m12 l4"> + <h6>{% trans "General" %}</h6> + <ul class="collection"> + <li class="collection-item chip-height"> + <strong>(a)</strong> {% trans "Absences" %} + <span class="chip secondary-color white-text right">0</span> + </li> + <li class="collection-item chip-height"> + <strong>(u)</strong> {% trans "Unexcused absences" %} + <span class="chip red white-text right">0</span> + </li> + <li class="collection-item chip-height"> + <strong>(e)</strong> {% trans "Excused absences" %} + <span class="chip green white-text right">0</span> + </li> + </ul> + </div> + + {% if excuse_types %} + <div class="col s12 m12 l4"> + <h6>{% trans "Excuse types" %}</h6> + + <ul class="collection"> + {% for excuse_type in excuse_types %} + <li class="collection-item chip-height"> + <strong>({{ excuse_type.short_name }})</strong> {{ excuse_type.name }} + <span class="chip grey white-text right">0</span> + </li> + {% endfor %} + </ul> + </div> + {% endif %} + + {% if extra_marks %} + <div class="col s12 m12 l4"> + <h6>{% trans "Extra marks" %}</h6> + + <ul class="collection"> + {% for extra_mark in extra_marks %} + <li class="collection-item chip-height"> + <strong>{{ extra_mark.short_name }}</strong> {{ extra_mark.name }} + <span class="chip grey white-text right">0</span> + </li> + {% endfor %} + </ul> + </div> + {% endif %} + </div> + </div> +</div> diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html index 57b71b661994baf0f2b37a71678098d564cc88ed..4ad4aa8251059cbe5453f24ca5e00cd6a4490bd2 100644 --- a/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html +++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html @@ -3,18 +3,18 @@ {% now_datetime as now_dt %} {% if period.has_documentation %} - <i class="material-icons green-text tooltipped {{ css_class }}" data-position="bottom" data-tooltip="{% trans "Data complete" %}" title="{% trans "Data complete" %}">check_circle</i> + <i class="material-icons green{% firstof color_suffix "-text"%} tooltipped {{ css_class }}" data-position="bottom" data-tooltip="{% trans "Data complete" %}" title="{% trans "Data complete" %}">check_circle</i> {% else %} {% period_to_time_start week period.period as time_start %} {% period_to_time_end week period.period as time_end %} {% if period.get_substitution.cancelled %} - <i class="material-icons red-text tooltipped {{ css_class }}" data-position="bottom" data-tooltip="{% trans "Lesson cancelled" %}" title="{% trans "Lesson cancelled" %}">cancel</i> + <i class="material-icons red{% firstof color_suffix "-text"%} tooltipped {{ css_class }}" data-position="bottom" data-tooltip="{% trans "Lesson cancelled" %}" title="{% trans "Lesson cancelled" %}">cancel</i> {% elif now_dt > time_end %} - <i class="material-icons red-text tooltipped {{ css_class }}" data-position="bottom" data-tooltip="{% trans "Missing data" %}" title="{% trans "Missing data" %}">history</i> + <i class="material-icons red{% firstof color_suffix "-text"%} tooltipped {{ css_class }}" data-position="bottom" data-tooltip="{% trans "Missing data" %}" title="{% trans "Missing data" %}">history</i> {% elif now_dt > time_start and now_dt < time_end %} - <i class="material-icons orange-text tooltipped {{ css_class }}" data-position="bottom" data-tooltip="{% trans "Pending" %}" title="{% trans "Pending" %}">more_horiz</i> + <i class="material-icons orange{% firstof color_suffix "-text"%} tooltipped {{ css_class }}" data-position="bottom" data-tooltip="{% trans "Pending" %}" title="{% trans "Pending" %}">more_horiz</i> {% elif period.get_substitution %} - <i class="material-icons orange-text tooltipped {{ css_class }}" data-position="bottom" data-tooltip="{% trans "Substitution" %}" title="{% trans "Substitution" %}">update</i> + <i class="material-icons orange{% firstof color_suffix "-text"%} tooltipped {{ css_class }}" data-position="bottom" data-tooltip="{% trans "Substitution" %}" title="{% trans "Substitution" %}">update</i> {% endif %} {% endif %} diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html b/aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html new file mode 100644 index 0000000000000000000000000000000000000000..25341b1a6deb1ae867000ad1b20f7ad5a46d7d1a --- /dev/null +++ b/aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html @@ -0,0 +1,122 @@ +{% load data_helpers time_helpers i18n rules %} + +{% if not persons %} + <div class="alert primary"> + <div> + <i class="material-icons left">warning</i> + {% blocktrans %}No students available.{% endblocktrans %} + </div> + </div> +{% else %} + <table class="highlight responsive-table"> + <thead> + <tr class="hide-on-med-and-down"> + <th rowspan="2">{% trans "Name" %}</th> + <th rowspan="2">{% trans "Primary group" %}</th> + <th colspan="{{ excuse_types.count|add:3 }}">{% trans "Absences" %}</th> + <th rowspan="2">{% trans "Tardiness" %}</th> + {% if extra_marks %} + <th colspan="{{ extra_marks.count }}">{% trans "Extra marks" %}</th> + {% endif %} + <th rowspan="2"></th> + </tr> + <tr class="hide-on-large-only"> + <th class="truncate">{% trans "Name" %}</th> + <th class="truncate">{% trans "Primary group" %}</th> + <th class="truncate chip-height">{% trans "Absences" %}</th> + <th class="chip-height">{% trans "(e)" %}</th> + {% for excuse_type in excuse_types %} + <th class="chip-height"> + ({{ excuse_type.short_name }}) + </th> + {% endfor %} + <th class="chip-height">{% trans "(u)" %}</th> + <th class="truncate chip-height">{% trans "Tardiness" %}</th> + {% for extra_mark in extra_marks %} + <th class="chip-height"> + {{ extra_mark.short_name }} + </th> + {% endfor %} + <th rowspan="2"></th> + </tr> + <tr class="hide-on-med-and-down"> + <th>{% trans "Sum" %}</th> + <th>{% trans "(e)" %}</th> + {% for excuse_type in excuse_types %} + <th> + ({{ excuse_type.short_name }}) + </th> + {% endfor %} + <th>{% trans "(u)" %}</th> + {% for extra_mark in extra_marks %} + <th> + {{ extra_mark.short_name }} + </th> + {% endfor %} + </tr> + </thead> + {% for person in persons %} + <tr> + <td> + <a href="{% url "overview_person" person.pk %}"> + {{ person }} + </a> + </td> + <td> + {% firstof person.primary_group "–" %} + </td> + <td> + <span class="chip secondary-color white-text" title="{% trans "Absences" %}"> + {{ person.absences_count }} + </span> + </td> + <td class="green-text"> + <span class="chip green white-text" title="{% trans "Excused" %}"> + {{ person.excused }} + </span> + </td> + {% for excuse_type in excuse_types %} + <td> + <span class="chip grey white-text" title="{{ excuse_type.name }}"> + {{ person|get_dict:excuse_type.count_label }} + </span> + </td> + {% endfor %} + <td class="red-text"> + <span class="chip red white-text" title="{% trans "Unexcused" %}"> + {{ person.unexcused }} + </span> + </td> + <td> + <span class="chip orange white-text" title="{% trans "Tardiness" %}"> + {% firstof person.tardiness|to_time|time:"H\h i\m" "–" %} + </span> + <span class="chip orange white-text" title="{% trans "Count of tardiness" %}">{{ person.tardiness_count }} ×</span> + </td> + {% for extra_mark in extra_marks %} + <td> + <span class="chip grey white-text" title="{{ extra_mark.name }}"> + {{ person|get_dict:extra_mark.count_label }} + </span> + </td> + {% endfor %} + + <td> + <a class="btn primary waves-effect waves-light" href="{% url "overview_person" person.pk %}"> + <i class="material-icons left">insert_chart</i> + <span class="hide-on-med-and-down"> {% trans "Show more details" %}</span> + <span class="hide-on-large-only">{% trans "Details" %}</span> + </a> + + {% has_perm "alsijil.register_absence" user person as can_register_absence %} + {% if can_register_absence %} + <a class="btn primary-color waves-effect waves-light" href="{% url "register_absence" person.pk %}"> + <i class="material-icons left">rate_review</i> + {% trans "Register absence" %} + </a> + {% endif %} + </td> + </tr> + {% endfor %} +{% endif %} +</table> diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/tardinesses.html b/aleksis/apps/alsijil/templates/alsijil/partials/tardinesses.html index b3639ea88b779bd746ab551f0a9f2e5d938fd786..3bb86191612f2bdface729be8d048a6fb05edcd5 100644 --- a/aleksis/apps/alsijil/templates/alsijil/partials/tardinesses.html +++ b/aleksis/apps/alsijil/templates/alsijil/partials/tardinesses.html @@ -1,3 +1,7 @@ +{% load rules %} {% for note in notes %} - <span>{{ note.person }} ({{ note.late }}'){% if not forloop.last %},{% endif %}</span> + {% has_perm "alsijil.view_personalnote" user note as can_view_personalnote %} + {% if can_view_personalnote %} + <span>{{ note.person }} ({{ note.late }}'){% if not forloop.last %},{% endif %}</span> + {% endif %} {% endfor %} diff --git a/aleksis/apps/alsijil/templates/alsijil/print/full_register.html b/aleksis/apps/alsijil/templates/alsijil/print/full_register.html index 03b75de7b70508885bf06f35e42d1058a5c80b1a..85ac0fbca5b83004f40621abc5a39bde0864dc47 100644 --- a/aleksis/apps/alsijil/templates/alsijil/print/full_register.html +++ b/aleksis/apps/alsijil/templates/alsijil/print/full_register.html @@ -149,7 +149,7 @@ <td>{{ person|get_dict:excuse_type.count_label }}</td> {% endfor %} <td>{{ person.unexcused }}</td> - <td>{{ person.tardiness }}'</td> + <td>{{ person.tardiness }}'/{{ person.tardiness_count }} ×</td> {% for extra_mark in extra_marks %} <td>{{ person|get_dict:extra_mark.count_label }}</td> {% endfor %} @@ -175,7 +175,7 @@ </thead> <tbody> - {% for lesson in group.lessons.all %} + {% for lesson in lessons %} <tr> <td>{{ lesson.subject.name }}</td> <td>{{ lesson.teachers.all|join:', ' }}</td> @@ -206,7 +206,7 @@ </thead> <tbody> - {% for child_group in group.child_groups.all %} + {% for child_group in child_groups %} {% for lesson in child_group.lessons.all %} <tr> <td>{{ child_group.name }}</td> @@ -285,7 +285,7 @@ </tr> <tr> <th colspan="2">{% trans 'Tardiness' %}</th> - <td>{{ person.tardiness }}'</td> + <td>{{ person.tardiness }}'/{{ person.tardiness_count }} ×</td> </tr> </table> diff --git a/aleksis/apps/alsijil/templatetags/__init__.py b/aleksis/apps/alsijil/templatetags/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/aleksis/apps/alsijil/templatetags/time_helpers.py b/aleksis/apps/alsijil/templatetags/time_helpers.py new file mode 100644 index 0000000000000000000000000000000000000000..cae2ee2e35ef5c25c338b617b784508185d669e8 --- /dev/null +++ b/aleksis/apps/alsijil/templatetags/time_helpers.py @@ -0,0 +1,14 @@ +import datetime + +from django import template + +register = template.Library() + + +@register.filter("to_time") +def get_time_from_minutes(minutes: int) -> datetime.timedelta: + """Get a time object from a number of minutes.""" + delta = datetime.timedelta(minutes=(minutes or 0)) + time_obj = (datetime.datetime.min + delta).time() + + return time_obj diff --git a/aleksis/apps/alsijil/urls.py b/aleksis/apps/alsijil/urls.py index 16f8a43ddc3438fdfbbc73729611a6249c8f5fa3..64393ba2084c5ff90fc080f34b2db5b16e643354 100644 --- a/aleksis/apps/alsijil/urls.py +++ b/aleksis/apps/alsijil/urls.py @@ -27,6 +27,7 @@ urlpatterns = [ "print/group/<int:id_>", views.full_register_group, name="full_register_group" ), path("groups/", views.my_groups, name="my_groups"), + path("groups/<int:pk>/", views.StudentsList.as_view(), name="students_list"), path("persons/", views.my_students, name="my_students"), path("persons/<int:id_>/", views.overview_person, name="overview_person"), path("me/", views.overview_person, name="overview_me"), @@ -35,7 +36,7 @@ urlpatterns = [ views.DeletePersonalNoteView.as_view(), name="delete_personal_note", ), - path("absence/new", views.register_absence, name="register_absence"), + path("absence/new/<int:id_>/", views.register_absence, name="register_absence"), path("extra_marks/", views.ExtraMarkListView.as_view(), name="extra_marks"), path( "extra_marks/create/", diff --git a/aleksis/apps/alsijil/util/alsijil_helpers.py b/aleksis/apps/alsijil/util/alsijil_helpers.py new file mode 100644 index 0000000000000000000000000000000000000000..10bf5b4e7e4c67b2f998209849e7fa60f5659945 --- /dev/null +++ b/aleksis/apps/alsijil/util/alsijil_helpers.py @@ -0,0 +1,52 @@ +from typing import Optional + +from django.http import HttpRequest + +from calendarweek import CalendarWeek + +from aleksis.apps.chronos.models import LessonPeriod +from aleksis.apps.chronos.util.chronos_helpers import get_el_by_pk + + +def get_lesson_period_by_pk( + request: HttpRequest, + year: Optional[int] = None, + week: Optional[int] = None, + period_id: Optional[int] = None, +): + """Get LessonPeriod object either by given object_id or by time and current person.""" + wanted_week = CalendarWeek(year=year, week=week) + if period_id: + lesson_period = LessonPeriod.objects.annotate_week(wanted_week).get( + pk=period_id + ) + elif hasattr(request, "user") and hasattr(request.user, "person"): + if request.user.person.lessons_as_teacher.exists(): + lesson_period = ( + LessonPeriod.objects.at_time() + .filter_teacher(request.user.person) + .first() + ) + else: + lesson_period = ( + LessonPeriod.objects.at_time() + .filter_participant(request.user.person) + .first() + ) + else: + lesson_period = None + return lesson_period + + +def get_timetable_instance_by_pk( + request: HttpRequest, + year: Optional[int] = None, + week: Optional[int] = None, + type_: Optional[str] = None, + id_: Optional[int] = None, +): + """Get timetable object (teacher, room or group) by given type and id or the current person.""" + if type_ and id_: + return get_el_by_pk(request, type_, id_) + elif hasattr(request, "user") and hasattr(request.user, "person"): + return request.user.person diff --git a/aleksis/apps/alsijil/util/predicates.py b/aleksis/apps/alsijil/util/predicates.py new file mode 100644 index 0000000000000000000000000000000000000000..4bdd2a34ca1bf7ed1e81777e4f99e493d071905c --- /dev/null +++ b/aleksis/apps/alsijil/util/predicates.py @@ -0,0 +1,268 @@ +from typing import Any, Union + +from django.contrib.auth.models import Permission, User + +from guardian.models import UserObjectPermission +from guardian.shortcuts import get_objects_for_user +from rules import predicate + +from aleksis.apps.chronos.models import LessonPeriod +from aleksis.core.models import Group, Person +from aleksis.core.util.core_helpers import get_content_type_by_perm, get_site_preferences +from aleksis.core.util.predicates import check_object_permission + +from ..models import PersonalNote + + +@predicate +def is_none(user: User, obj: Any) -> bool: + """Predicate that checks if the provided object is None-like.""" + return bool(obj) + + +@predicate +def is_lesson_teacher(user: User, obj: LessonPeriod) -> bool: + """Predicate for teachers of a lesson. + + Checks whether the person linked to the user is a teacher + in the lesson or the substitution linked to the given LessonPeriod. + """ + if obj: + sub = obj.get_substitution() + if sub and sub in user.person.lesson_substitutions.all(): + return True + return user.person in obj.lesson.teachers.all() + return False + + +@predicate +def is_lesson_participant(user: User, obj: LessonPeriod) -> bool: + """Predicate for participants of a lesson. + + Checks whether the person linked to the user is a member in + the groups linked to the given LessonPeriod. + """ + if hasattr(obj, "lesson"): + for group in obj.lesson.groups.all(): + if user.person in list(group.members.all()): + return True + return False + + +@predicate +def is_lesson_parent_group_owner(user: User, obj: LessonPeriod) -> bool: + """ + Predicate for parent group owners of a lesson. + + Checks whether the person linked to the user is the owner of + any parent groups of any groups of the given LessonPeriods lesson. + """ + if hasattr(obj, "lesson"): + for group in obj.lesson.groups.all(): + for parent_group in group.parent_groups.all(): + if user.person in list(parent_group.owners.all()): + return True + return False + + +@predicate +def is_group_owner(user: User, obj: Union[Group, Person]) -> bool: + """Predicate for group owners of a given group. + + Checks whether the person linked to the user is the owner of the given group. + If there isn't provided a group, it will return `False`. + """ + if isinstance(obj, Group): + if user.person in obj.owners.all(): + return True + + return False + + +@predicate +def is_person_group_owner(user: User, obj: Person) -> bool: + """ + Predicate for group owners of any group. + + Checks whether the person linked to the user is + the owner of any group of the given person. + """ + if obj: + for group in obj.member_of.all(): + if user.person in list(group.owners.all()): + return True + return False + return False + + +@predicate +def is_person_primary_group_owner(user: User, obj: Person) -> bool: + """ + Predicate for group owners of the person's primary group. + + Checks whether the person linked to the user is + the owner of the primary group of the given person. + """ + if obj.primary_group: + return user.person in obj.primary_group.owners.all() + return False + + +def has_person_group_object_perm(perm: str): + """Predicate builder for permissions on a set of member groups. + + Checks whether a user has a permission on any group of a person. + """ + name = f"has_person_group_object_perm:{perm}" + + ct = get_content_type_by_perm(perm) + permissions = Permission.objects.filter(content_type=ct, codename=perm) + + @predicate(name) + def fn(user: User, obj: Person) -> bool: + groups = obj.member_of.all() + qs = UserObjectPermission.objects.filter( + object_pk__in=list(groups.values_list("pk", flat=True)), + content_type=ct, + user=user, + permission__in=permissions, + ) + return qs.exists() + + return fn + + +@predicate +def is_group_member(user: User, obj: Union[Group, Person]) -> bool: + """Predicate for group membership. + + Checks whether the person linked to the user is a member of the given group. + If there isn't provided a group, it will return `False`. + """ + if isinstance(obj, Group): + if user.person in obj.members.all(): + return True + + return False + + +def has_lesson_group_object_perm(perm: str): + """Predicate builder for permissions on lesson groups. + + Checks whether a user has a permission on any group of a LessonPeriod. + """ + name = f"has_lesson_group_object_perm:{perm}" + + ct = get_content_type_by_perm(perm) + permissions = Permission.objects.filter(content_type=ct, codename=perm) + + @predicate(name) + def fn(user: User, obj: LessonPeriod) -> bool: + if hasattr(obj, "lesson"): + groups = obj.lesson.groups.all() + qs = UserObjectPermission.objects.filter( + object_pk__in=list(groups.values_list("pk", flat=True)), + content_type=ct, + user=user, + permission__in=permissions, + ) + return qs.exists() + return False + + return fn + + +def has_personal_note_group_perm(perm: str): + """Predicate builder for permissions on personal notes + + Checks whether a user has a permission on any group of a person of a PersonalNote. + """ + name = f"has_personal_note_person_or_group_perm:{perm}" + + ct = get_content_type_by_perm(perm) + permissions = Permission.objects.filter(content_type=ct, codename=perm) + + @predicate(name) + def fn(user: User, obj: PersonalNote) -> bool: + if hasattr(obj, "person"): + groups = obj.person.member_of.all() + qs = UserObjectPermission.objects.filter( + object_pk__in=list(groups.values_list("pk", flat=True)), + content_type=ct, + user=user, + permission__in=permissions, + ) + return qs.exists() + return False + + return fn + + +@predicate +def is_own_personal_note(user: User, obj: PersonalNote) -> bool: + """Predicate for users referred to in a personal note + + Checks whether the user referred to in a PersonalNote is the active user. + """ + if hasattr(obj, "person") and obj.person is user.person: + return True + return False + + +@predicate +def is_personal_note_lesson_teacher(user: User, obj: PersonalNote) -> bool: + """Predicate for teachers of a lesson referred to in the lesson period of a personal note. + + Checks whether the person linked to the user is a teacher + in the lesson or the substitution linked to the LessonPeriod of the given PersonalNote. + """ + if hasattr(obj, "lesson_period"): + if hasattr(obj.lesson_period, "lesson"): + sub = obj.lesson_period.get_substitution() + if sub and user.person in Person.objects.filter( + lesson_substitutions=obj.lesson_period.get_substitution() + ): + return True + + return user.person in obj.lesson_period.lesson.teachers.all() + + return False + return False + + +@predicate +def is_personal_note_lesson_parent_group_owner(user: User, obj: PersonalNote) -> bool: + """ + Predicate for parent group owners of a lesson referred to in the lesson period of a personal note. + + Checks whether the person linked to the user is the owner of + any parent groups of any groups of the given LessonPeriod lesson of the given PersonalNote. + """ + if hasattr(obj, "lesson_period"): + if hasattr(obj.lesson_period, "lesson"): + for group in obj.lesson_period.lesson.groups.all(): + for parent_group in group.parent_groups.all(): + if user.person in list(parent_group.owners.all()): + return True + return False + + +@predicate +def has_any_object_absence(user: User) -> bool: + """ + Predicate which builds a query with all the persons the given users is allowed to register an absence for. + """ + if Person.objects.filter(member_of__owners=user.person).exists(): + return True + if get_objects_for_user(user, "core.register_absence_person", Person).exists(): + return True + if Person.objects.filter( + member_of__in=get_objects_for_user(user, "core.register_absence_group", Group) + ).exists(): + return True + + +@predicate +def is_teacher(user: User, obj: Person) -> bool: + """Predicate which checks if the provided object is a teacher.""" + return user.person.is_teacher diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py index cb4ca7ab796b7c7452d0a25f578bb716becb9be5..9bcaecac84b45a2dfcfe81e74f9bcb9cc79d0bc2 100644 --- a/aleksis/apps/alsijil/views.py +++ b/aleksis/apps/alsijil/views.py @@ -2,7 +2,7 @@ from datetime import date, datetime, timedelta from typing import Any, Dict, Optional from django.core.exceptions import PermissionDenied -from django.db.models import Count, Exists, OuterRef, Q, QuerySet, Subquery, Sum +from django.db.models import Count, Exists, OuterRef, Prefetch, Q, QuerySet, Subquery, Sum from django.http import Http404, HttpRequest, HttpResponse, HttpResponseNotFound from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse, reverse_lazy @@ -13,11 +13,11 @@ import reversion from calendarweek import CalendarWeek from django_tables2 import SingleTableView from reversion.views import RevisionMixin -from rules.contrib.views import PermissionRequiredMixin +from rules.contrib.views import PermissionRequiredMixin, permission_required from aleksis.apps.alsijil.data_checks import check_data from aleksis.apps.chronos.managers import TimetableType -from aleksis.apps.chronos.models import LessonPeriod, TimePeriod +from aleksis.apps.chronos.models import LessonPeriod, LessonSubstitution, TimePeriod from aleksis.apps.chronos.util.chronos_helpers import get_el_by_pk from aleksis.apps.chronos.util.date import get_weeks_for_year, week_weekday_to_date from aleksis.core.mixins import AdvancedCreateView, AdvancedDeleteView, AdvancedEditView @@ -37,16 +37,12 @@ from .forms import ( RegisterAbsenceForm, SelectForm, ) -from .models import ( - DataCheckResult, - ExcuseType, - ExtraMark, - LessonDocumentation, - PersonalNote, -) +from .models import DataCheckResult, ExcuseType, ExtraMark, LessonDocumentation, PersonalNote from .tables import ExcuseTypeTable, ExtraMarkTable +from .util.alsijil_helpers import get_lesson_period_by_pk, get_timetable_instance_by_pk +@permission_required("alsijil.view_lesson", fn=get_lesson_period_by_pk) def lesson( request: HttpRequest, year: Optional[int] = None, @@ -55,27 +51,16 @@ def lesson( ) -> HttpResponse: context = {} - if year and week and period_id: - # Get a specific lesson period if provided in URL - wanted_week = CalendarWeek(year=year, week=week) - lesson_period = LessonPeriod.objects.annotate_week(wanted_week).get( - pk=period_id - ) + lesson_period = get_lesson_period_by_pk(request, year, week, period_id) - date_of_lesson = week_weekday_to_date(wanted_week, lesson_period.period.weekday) - - if ( - date_of_lesson < lesson_period.lesson.validity.date_start - or date_of_lesson > lesson_period.lesson.validity.date_end - ): - return HttpResponseNotFound() - else: - # Determine current lesson by current date and time - lesson_period = ( - LessonPeriod.objects.at_time().filter_teacher(request.user.person).first() - ) + if period_id: + wanted_week = CalendarWeek(year=year, week=week) + elif hasattr(request, "user") and hasattr(request.user, "person"): wanted_week = CalendarWeek() + else: + wanted_week = None + if not all((year, week, period_id)): if lesson_period: return redirect( "lesson_by_week_and_period", @@ -91,6 +76,14 @@ def lesson( ) ) + date_of_lesson = week_weekday_to_date(wanted_week, lesson_period.period.weekday) + + if ( + date_of_lesson < lesson_period.lesson.validity.date_start + or date_of_lesson > lesson_period.lesson.validity.date_end + ): + return HttpResponseNotFound() + if ( datetime.combine( wanted_week[lesson_period.period.weekday], lesson_period.period.time_start, @@ -108,9 +101,14 @@ def lesson( ) ) + next_lesson = request.user.person.next_lesson(lesson_period, date_of_lesson) + prev_lesson = request.user.person.previous_lesson(lesson_period, date_of_lesson) + context["lesson_period"] = lesson_period context["week"] = wanted_week context["day"] = wanted_week[lesson_period.period.weekday] + context["next_lesson_person"] = next_lesson + context["prev_lesson_person"] = prev_lesson # Create or get lesson documentation object; can be empty when first opening lesson lesson_documentation = lesson_period.get_or_create_lesson_documentation(wanted_week) @@ -121,13 +119,20 @@ def lesson( ) # Create a formset that holds all personal notes for all persons in this lesson - persons_qs = lesson_period.get_personal_notes(wanted_week) + if not request.user.has_perm("alsijil.view_lesson_personalnote", lesson_period): + persons = Person.objects.filter(pk=request.user.person.pk) + else: + persons = Person.objects.all() + + persons_qs = lesson_period.get_personal_notes(persons, wanted_week) personal_note_formset = PersonalNoteFormSet( request.POST or None, queryset=persons_qs, prefix="personal_notes" ) if request.method == "POST": - if lesson_documentation_form.is_valid(): + if lesson_documentation_form.is_valid() and request.user.has_perm( + "alsijil.edit_lessondocumentation", lesson_period + ): lesson_documentation_form.save() messages.success(request, _("The lesson documentation has been saved.")) @@ -137,7 +142,9 @@ def lesson( not getattr(substitution, "cancelled", False) or not get_site_preferences()["alsijil__block_personal_notes_for_cancelled"] ): - if personal_note_formset.is_valid(): + if personal_note_formset.is_valid() and request.user.has_perm( + "alsijil.edit_lesson_personalnote", lesson_period + ): with reversion.create_revision(): instances = personal_note_formset.save() @@ -161,10 +168,13 @@ def lesson( context["lesson_documentation"] = lesson_documentation context["lesson_documentation_form"] = lesson_documentation_form context["personal_note_formset"] = personal_note_formset + context["prev_lesson"] = lesson_period.prev + context["next_lesson"] = lesson_period.next return render(request, "alsijil/class_register/lesson.html", context) +@permission_required("alsijil.view_week", fn=get_timetable_instance_by_pk) def week_view( request: HttpRequest, year: Optional[int] = None, @@ -179,38 +189,30 @@ def week_view( else: wanted_week = CalendarWeek() - lesson_periods = LessonPeriod.objects.annotate( - has_documentation=Exists( - LessonDocumentation.objects.filter( - ~Q(topic__exact=""), - lesson_period=OuterRef("pk"), - week=wanted_week.week, - year=wanted_week.year, - ) - ) - ).in_week(wanted_week) + instance = get_timetable_instance_by_pk(request, year, week, type_, id_) - group = None - if type_ and id_: - instance = get_el_by_pk(request, type_, id_) + lesson_periods = LessonPeriod.objects.in_week(wanted_week).prefetch_related( + "lesson__groups__members", + "lesson__groups__parent_groups", + "lesson__groups__parent_groups__owners", + ) + lesson_periods_query_exists = True + if type_ and id_: if isinstance(instance, HttpResponseNotFound): return HttpResponseNotFound() type_ = TimetableType.from_string(type_) - if type_ == TimetableType.GROUP: - group = instance - lesson_periods = lesson_periods.filter_from_type(type_, instance) elif hasattr(request, "user") and hasattr(request.user, "person"): - instance = request.user.person if request.user.person.lessons_as_teacher.exists(): lesson_periods = lesson_periods.filter_teacher(request.user.person) type_ = TimetableType.TEACHER else: lesson_periods = lesson_periods.filter_participant(request.user.person) else: + lesson_periods_query_exists = False lesson_periods = None # Add a form to filter the view @@ -233,13 +235,48 @@ def week_view( select_form.cleaned_data["instance"].pk, ) - if lesson_periods: - # Aggregate all personal notes for this group and week + if type_ == TimetableType.GROUP: + group = instance + else: + group = None + + extra_marks = ExtraMark.objects.all() + + if lesson_periods_query_exists: lesson_periods_pk = list(lesson_periods.values_list("pk", flat=True)) + lesson_periods = ( + LessonPeriod.objects.prefetch_related( + Prefetch( + "documentations", + queryset=LessonDocumentation.objects.filter( + week=wanted_week.week, year=wanted_week.year + ), + ) + ) + .filter(pk__in=lesson_periods_pk) + .annotate_week(wanted_week) + .annotate( + has_documentation=Exists( + LessonDocumentation.objects.filter( + ~Q(topic__exact=""), + lesson_period=OuterRef("pk"), + week=wanted_week.week, + year=wanted_week.year, + ) + ) + ) + .order_by("period__weekday", "period__period") + ) + else: + lesson_periods_pk = [] + if lesson_periods_pk: + # Aggregate all personal notes for this group and week persons_qs = Person.objects.filter(is_active=True) - if group: + if not request.user.has_perm("alsijil.view_week_personalnote", instance): + persons_qs = persons_qs.filter(pk=request.user.person.pk) + elif group: persons_qs = persons_qs.filter(member_of=group) else: persons_qs = persons_qs.filter( @@ -248,7 +285,17 @@ def week_view( persons_qs = ( persons_qs.distinct() - .prefetch_related("personal_notes") + .prefetch_related( + Prefetch( + "personal_notes", + queryset=PersonalNote.objects.filter( + week=wanted_week.week, + year=wanted_week.year, + lesson_period__in=lesson_periods_pk, + ), + ), + "member_of__owners", + ) .annotate( absences_count=Count( "personal_notes", @@ -282,10 +329,20 @@ def week_view( .annotate(tardiness_sum=Sum("personal_notes__late")) .values("tardiness_sum") ), + tardiness_count=Count( + "personal_notes", + filter=Q( + personal_notes__lesson_period__in=lesson_periods_pk, + personal_notes__week=wanted_week.week, + personal_notes__year=wanted_week.year, + ) + & ~Q(personal_notes__late=0), + distinct=True, + ), ) ) - for extra_mark in ExtraMark.objects.all(): + for extra_mark in extra_marks: persons_qs = persons_qs.annotate( **{ extra_mark.count_label: Count( @@ -304,24 +361,12 @@ def week_view( persons = [] for person in persons_qs: persons.append( - { - "person": person, - "personal_notes": person.personal_notes.filter( - week=wanted_week.week, - year=wanted_week.year, - lesson_period__in=lesson_periods_pk, - ), - } + {"person": person, "personal_notes": list(person.personal_notes.all())} ) else: persons = None - # Resort lesson periods manually because an union queryset doesn't support order_by - lesson_periods = sorted( - lesson_periods, key=lambda x: (x.period.weekday, x.period.period) - ) - - context["extra_marks"] = ExtraMark.objects.all() + context["extra_marks"] = extra_marks context["week"] = wanted_week context["weeks"] = get_weeks_for_year(year=wanted_week.year) context["lesson_periods"] = lesson_periods @@ -351,26 +396,30 @@ def week_view( return render(request, "alsijil/class_register/week_view.html", context) +@permission_required( + "alsijil.view_full_register", fn=objectgetter_optional(Group, None, False) +) def full_register_group(request: HttpRequest, id_: int) -> HttpResponse: context = {} group = get_object_or_404(Group, pk=id_) - current_school_term = SchoolTerm.current - - if not current_school_term: - return HttpResponseNotFound(_("There is no current school term.")) - # Get all lesson periods for the selected group lesson_periods = ( LessonPeriod.objects.filter_group(group) - .filter(lesson__validity__school_term=current_school_term) .distinct() - .prefetch_related("documentations", "personal_notes") + .prefetch_related( + "documentations", + "personal_notes", + "personal_notes__excuse_type", + "personal_notes__extra_marks", + "personal_notes__person", + "personal_notes__groups_of_person", + ) ) weeks = CalendarWeek.weeks_within( - current_school_term.date_start, current_school_term.date_end, + group.school_term.date_start, group.school_term.date_end, ) periods_by_day = {} @@ -401,65 +450,20 @@ def full_register_group(request: HttpRequest, id_: int) -> HttpResponse: (lesson_period, documentations, notes, substitution) ) - persons = Person.objects.filter( - personal_notes__groups_of_person=group, - personal_notes__lesson_period__lesson__validity__school_term=current_school_term, - ).annotate( - absences_count=Count( - "personal_notes__absent", - filter=Q( - personal_notes__absent=True, - personal_notes__lesson_period__lesson__validity__school_term=current_school_term, - ), - ), - excused=Count( - "personal_notes__absent", - filter=Q( - personal_notes__absent=True, - personal_notes__excused=True, - personal_notes__excuse_type__isnull=True, - personal_notes__lesson_period__lesson__validity__school_term=current_school_term, - ), - ), - unexcused=Count( - "personal_notes__absent", - filter=Q( - personal_notes__absent=True, - personal_notes__excused=False, - personal_notes__lesson_period__lesson__validity__school_term=current_school_term, - ), - ), - tardiness=Sum("personal_notes__late"), + persons = Person.objects.prefetch_related( + "personal_notes", + "personal_notes__excuse_type", + "personal_notes__extra_marks", + "personal_notes__lesson_period__lesson__subject", + "personal_notes__lesson_period__substitutions", + "personal_notes__lesson_period__substitutions__subject", + "personal_notes__lesson_period__substitutions__teachers", + "personal_notes__lesson_period__lesson__teachers", + "personal_notes__lesson_period__period", ) + persons = group.generate_person_list_with_class_register_statistics(persons) - for extra_mark in ExtraMark.objects.all(): - persons = persons.annotate( - **{ - extra_mark.count_label: Count( - "personal_notes", - filter=Q( - personal_notes__extra_marks=extra_mark, - personal_notes__lesson_period__lesson__validity__school_term=current_school_term, - ), - ) - } - ) - - for excuse_type in ExcuseType.objects.all(): - persons = persons.annotate( - **{ - excuse_type.count_label: Count( - "personal_notes__absent", - filter=Q( - personal_notes__absent=True, - personal_notes__excuse_type=excuse_type, - personal_notes__lesson_period__lesson__validity__school_term=current_school_term, - ), - ) - } - ) - - context["school_term"] = current_school_term + context["school_term"] = group.school_term context["persons"] = persons context["excuse_types"] = ExcuseType.objects.all() context["extra_marks"] = ExtraMark.objects.all() @@ -468,33 +472,73 @@ def full_register_group(request: HttpRequest, id_: int) -> HttpResponse: context["periods_by_day"] = periods_by_day context["lesson_periods"] = lesson_periods context["today"] = date.today() - + context["lessons"] = ( + group.lessons.all() + .select_related("validity", "subject") + .prefetch_related("teachers", "lesson_periods") + ) + context["child_groups"] = group.child_groups.all().prefetch_related( + "lessons", + "lessons__validity", + "lessons__subject", + "lessons__teachers", + "lessons__lesson_periods", + ) return render(request, "alsijil/print/full_register.html", context) +@permission_required("alsijil.view_my_students") def my_students(request: HttpRequest) -> HttpResponse: context = {} relevant_groups = ( - Group.objects.for_current_school_term_or_all() - .annotate(lessons_count=Count("lessons")) - .filter(lessons_count__gt=0, owners=request.user.person) + request.user.person.get_owner_groups_with_lessons() + .annotate(has_parents=Exists(Group.objects.filter(child_groups=OuterRef("pk")))) + .filter(members__isnull=False) + .order_by("has_parents", "name") + .prefetch_related("members") + .distinct() ) - persons = Person.objects.filter(member_of__in=relevant_groups) - context["persons"] = persons + + new_groups = [] + for group in relevant_groups: + persons = group.generate_person_list_with_class_register_statistics() + new_groups.append((group, persons)) + + context["groups"] = new_groups + context["excuse_types"] = ExcuseType.objects.all() + context["extra_marks"] = ExtraMark.objects.all() return render(request, "alsijil/class_register/persons.html", context) +@permission_required("alsijil.view_my_groups",) def my_groups(request: HttpRequest) -> HttpResponse: context = {} - groups = ( - Group.objects.for_current_school_term_or_all() - .annotate(lessons_count=Count("lessons")) - .filter(lessons_count__gt=0, owners=request.user.person) + context["groups"] = request.user.person.get_owner_groups_with_lessons().annotate( + students_count=Count("members") ) - context["groups"] = groups return render(request, "alsijil/class_register/groups.html", context) +class StudentsList(PermissionRequiredMixin, DetailView): + model = Group + template_name = "alsijil/class_register/students_list.html" + permission_required = "alsijil.view_students_list" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["group"] = self.object + context[ + "persons" + ] = self.object.generate_person_list_with_class_register_statistics() + context["extra_marks"] = ExtraMark.objects.all() + context["excuse_types"] = ExcuseType.objects.all() + return context + + +@permission_required( + "alsijil.view_person_overview", + fn=objectgetter_optional(Person, "request.user.person", True), +) def overview_person(request: HttpRequest, id_: Optional[int] = None) -> HttpResponse: context = {} person = objectgetter_optional( @@ -525,6 +569,11 @@ def overview_person(request: HttpRequest, id_: Optional[int] = None) -> HttpResp request.POST["date"], "%Y-%m-%d" ).date() + if not request.user.has_perm( + "alsijil.edit_person_overview_personalnote", person + ): + raise PermissionDenied() + notes = person.personal_notes.filter( week=date.isocalendar()[1], lesson_period__period__weekday=date.weekday(), @@ -550,6 +599,8 @@ def overview_person(request: HttpRequest, id_: Optional[int] = None) -> HttpResp note = PersonalNote.objects.get( pk=int(request.POST["personal_note"]) ) + if not request.user.has_perm("alsijil.edit_personalnote", note): + raise PermissionDenied() if note.absent: note.excused = True note.excuse_type = excuse_type @@ -563,10 +614,23 @@ def overview_person(request: HttpRequest, id_: Optional[int] = None) -> HttpResp person.refresh_from_db() - unexcused_absences = person.personal_notes.filter(absent=True, excused=False) + person_personal_notes = person.personal_notes.all().prefetch_related( + "lesson_period__lesson__groups", + "lesson_period__lesson__teachers", + "lesson_period__substitutions", + ) + + if request.user.has_perm("alsijil.view_person_overview_personalnote", person): + allowed_personal_notes = person_personal_notes.all() + else: + allowed_personal_notes = person_personal_notes.filter( + lesson_period__lesson__groups__owners=request.user.person + ) + + unexcused_absences = allowed_personal_notes.filter(absent=True, excused=False) context["unexcused_absences"] = unexcused_absences - personal_notes = person.personal_notes.filter( + personal_notes = allowed_personal_notes.filter( Q(absent=True) | Q(late__gt=0) | ~Q(remarks="") | Q(extra_marks__isnull=False) ).order_by( "-lesson_period__lesson__validity__date_start", @@ -577,101 +641,115 @@ def overview_person(request: HttpRequest, id_: Optional[int] = None) -> HttpResp context["personal_notes"] = personal_notes context["excuse_types"] = ExcuseType.objects.all() - school_terms = SchoolTerm.objects.all().order_by("-date_start") - stats = [] - for school_term in school_terms: - stat = {} - personal_notes = PersonalNote.objects.filter( - person=person, lesson_period__lesson__validity__school_term=school_term - ) + extra_marks = ExtraMark.objects.all() + excuse_types = ExcuseType.objects.all() + if request.user.has_perm("alsijil.view_person_statistics_personalnote", person): + school_terms = SchoolTerm.objects.all().order_by("-date_start") + stats = [] + for school_term in school_terms: + stat = {} + personal_notes = PersonalNote.objects.filter( + person=person, lesson_period__lesson__validity__school_term=school_term + ) - if not personal_notes.exists(): - continue + if not personal_notes.exists(): + continue - stat.update( - personal_notes.filter(absent=True).aggregate(absences_count=Count("absent")) - ) - stat.update( - personal_notes.filter( - absent=True, excused=True, excuse_type__isnull=True - ).aggregate(excused=Count("absent")) - ) - stat.update( - personal_notes.filter(absent=True, excused=False).aggregate( - unexcused=Count("absent") + stat.update( + personal_notes.filter(absent=True).aggregate( + absences_count=Count("absent") + ) + ) + stat.update( + personal_notes.filter( + absent=True, excused=True, excuse_type__isnull=True + ).aggregate(excused=Count("absent")) ) - ) - stat.update(personal_notes.aggregate(tardiness=Sum("late"))) - - for extra_mark in ExtraMark.objects.all(): stat.update( - personal_notes.filter(extra_marks=extra_mark).aggregate( - **{extra_mark.count_label: Count("pk")} + personal_notes.filter(absent=True, excused=False).aggregate( + unexcused=Count("absent") ) ) - - for excuse_type in ExcuseType.objects.all(): + stat.update(personal_notes.aggregate(tardiness=Sum("late"))) stat.update( - personal_notes.filter(absent=True, excuse_type=excuse_type).aggregate( - **{excuse_type.count_label: Count("absent")} + personal_notes.filter(~Q(late=0)).aggregate( + tardiness_count=Count("late") ) ) - stats.append((school_term, stat)) - context["stats"] = stats - context["excuse_types"] = ExcuseType.objects.all() - context["extra_marks"] = ExtraMark.objects.all() + for extra_mark in extra_marks: + stat.update( + personal_notes.filter(extra_marks=extra_mark).aggregate( + **{extra_mark.count_label: Count("pk")} + ) + ) + + for excuse_type in excuse_types: + stat.update( + personal_notes.filter( + absent=True, excuse_type=excuse_type + ).aggregate(**{excuse_type.count_label: Count("absent")}) + ) + + stats.append((school_term, stat)) + context["stats"] = stats + + context["excuse_types"] = excuse_types + context["extra_marks"] = extra_marks + return render(request, "alsijil/class_register/person.html", context) -def register_absence(request: HttpRequest) -> HttpResponse: +@permission_required("alsijil.register_absence", fn=objectgetter_optional(Person)) +def register_absence(request: HttpRequest, id_: int) -> HttpResponse: context = {} + person = get_object_or_404(Person, pk=id_) + register_absence_form = RegisterAbsenceForm(request.POST or None) - if request.method == "POST": - if register_absence_form.is_valid(): - # Get data from form - person = register_absence_form.cleaned_data["person"] - start_date = register_absence_form.cleaned_data["date_start"] - end_date = register_absence_form.cleaned_data["date_end"] - from_period = register_absence_form.cleaned_data["from_period"] - to_period = register_absence_form.cleaned_data["to_period"] - absent = register_absence_form.cleaned_data["absent"] - excused = register_absence_form.cleaned_data["excused"] - excuse_type = register_absence_form.cleaned_data["excuse_type"] - remarks = register_absence_form.cleaned_data["remarks"] - - # Mark person as absent - delta = end_date - start_date - for i in range(delta.days + 1): - from_period_on_day = from_period if i == 0 else TimePeriod.period_min - to_period_on_day = ( - to_period if i == delta.days else TimePeriod.period_max - ) - day = start_date + timedelta(days=i) - - person.mark_absent( - day, - from_period_on_day, - absent, - excused, - excuse_type, - remarks, - to_period_on_day, - ) + if request.method == "POST" and register_absence_form.is_valid(): + # Get data from form + # person = register_absence_form.cleaned_data["person"] + start_date = register_absence_form.cleaned_data["date_start"] + end_date = register_absence_form.cleaned_data["date_end"] + from_period = register_absence_form.cleaned_data["from_period"] + to_period = register_absence_form.cleaned_data["to_period"] + absent = register_absence_form.cleaned_data["absent"] + excused = register_absence_form.cleaned_data["excused"] + excuse_type = register_absence_form.cleaned_data["excuse_type"] + remarks = register_absence_form.cleaned_data["remarks"] + + # Mark person as absent + delta = end_date - start_date + for i in range(delta.days + 1): + from_period_on_day = from_period if i == 0 else TimePeriod.period_min + to_period_on_day = to_period if i == delta.days else TimePeriod.period_max + day = start_date + timedelta(days=i) + + person.mark_absent( + day, + from_period_on_day, + absent, + excused, + excuse_type, + remarks, + to_period_on_day, + ) - messages.success(request, _("The absence has been saved.")) - return redirect("register_absence") + messages.success(request, _("The absence has been saved.")) + return redirect("overview_person", person.pk) + context["person"] = person context["register_absence_form"] = register_absence_form return render(request, "alsijil/absences/register.html", context) -class DeletePersonalNoteView(DetailView): +class DeletePersonalNoteView(PermissionRequiredMixin, DetailView): model = PersonalNote template_name = "core/pages/delete.html" + permission_required = "alsijil.edit_personalnote" def post(self, request, *args, **kwargs): note = self.get_object() @@ -682,83 +760,83 @@ class DeletePersonalNoteView(DetailView): return redirect("overview_person", note.person.pk) -class ExtraMarkListView(SingleTableView, PermissionRequiredMixin): +class ExtraMarkListView(PermissionRequiredMixin, SingleTableView): """Table of all extra marks.""" model = ExtraMark table_class = ExtraMarkTable - permission_required = "core.view_extramark" + permission_required = "alsijil.view_extramark" template_name = "alsijil/extra_mark/list.html" -class ExtraMarkCreateView(AdvancedCreateView, PermissionRequiredMixin): +class ExtraMarkCreateView(PermissionRequiredMixin, AdvancedCreateView): """Create view for extra marks.""" model = ExtraMark form_class = ExtraMarkForm - permission_required = "core.create_extramark" + permission_required = "alsijil.create_extramark" template_name = "alsijil/extra_mark/create.html" success_url = reverse_lazy("extra_marks") success_message = _("The extra mark has been created.") -class ExtraMarkEditView(AdvancedEditView, PermissionRequiredMixin): +class ExtraMarkEditView(PermissionRequiredMixin, AdvancedEditView): """Edit view for extra marks.""" model = ExtraMark form_class = ExtraMarkForm - permission_required = "core.edit_extramark" + permission_required = "alsijil.edit_extramark" template_name = "alsijil/extra_mark/edit.html" success_url = reverse_lazy("extra_marks") success_message = _("The extra mark has been saved.") -class ExtraMarkDeleteView(AdvancedDeleteView, PermissionRequiredMixin, RevisionMixin): +class ExtraMarkDeleteView(PermissionRequiredMixin, RevisionMixin, AdvancedDeleteView): """Delete view for extra marks""" model = ExtraMark - permission_required = "core.delete_extramark" + permission_required = "alsijil.delete_extramark" template_name = "core/pages/delete.html" success_url = reverse_lazy("extra_marks") success_message = _("The extra mark has been deleted.") -class ExcuseTypeListView(SingleTableView, PermissionRequiredMixin): +class ExcuseTypeListView(PermissionRequiredMixin, SingleTableView): """Table of all excuse types.""" model = ExcuseType table_class = ExcuseTypeTable - permission_required = "core.view_excusetype" + permission_required = "alsijil.view_excusetypes" template_name = "alsijil/excuse_type/list.html" -class ExcuseTypeCreateView(AdvancedCreateView, PermissionRequiredMixin): +class ExcuseTypeCreateView(PermissionRequiredMixin, AdvancedCreateView): """Create view for excuse types.""" model = ExcuseType form_class = ExcuseTypeForm - permission_required = "core.create_excusetype" + permission_required = "alsijil.add_excusetype" template_name = "alsijil/excuse_type/create.html" success_url = reverse_lazy("excuse_types") success_message = _("The excuse type has been created.") -class ExcuseTypeEditView(AdvancedEditView, PermissionRequiredMixin): +class ExcuseTypeEditView(PermissionRequiredMixin, AdvancedEditView): """Edit view for excuse types.""" model = ExcuseType form_class = ExcuseTypeForm - permission_required = "core.edit_excusetype" + permission_required = "alsijil.edit_excusetype" template_name = "alsijil/excuse_type/edit.html" success_url = reverse_lazy("excuse_types") success_message = _("The excuse type has been saved.") -class ExcuseTypeDeleteView(AdvancedDeleteView, PermissionRequiredMixin, RevisionMixin): +class ExcuseTypeDeleteView(PermissionRequiredMixin, RevisionMixin, AdvancedDeleteView): """Delete view for excuse types""" model = ExcuseType - permission_required = "core.delete_excusetype" + permission_required = "alsijil.delete_excusetype" template_name = "core/pages/delete.html" success_url = reverse_lazy("excuse_types") success_message = _("The excuse type has been deleted.") diff --git a/poetry.lock b/poetry.lock index 6869ab2867552636ad4b834e68ba13ca26fb47c9..18e7f5750cbdc124e34120411f8b9e67234bc11e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -68,11 +68,11 @@ extras = ["phonenumbers"] version = ">=3.0,<4.0" [package.dependencies.django-two-factor-auth] -extras = ["yubikey", "call", "phonenumbers", "sms"] +extras = ["yubikey", "phonenumbers", "sms", "call"] version = ">=1.11.0,<2.0.0" [package.dependencies.dynaconf] -extras = ["ini", "yaml", "toml"] +extras = ["ini", "toml", "yaml"] version = ">=2.0,<3.0" [package.extras] @@ -1035,7 +1035,7 @@ description = "Python docstring reStructuredText (RST) validator" name = "flake8-rst-docstrings" optional = false python-versions = "*" -version = "0.0.13" +version = "0.0.14" [package.dependencies] flake8 = ">=3.0.0" @@ -1949,7 +1949,7 @@ docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] testing = ["jaraco.itertools", "func-timeout"] [metadata] -content-hash = "4345c57e5e3244ce0bbdc8ad8a7cffa385fe33b7da1b5fc87ffe32dabf45c5a9" +content-hash = "f647d48cd770fea71d41ea5c67cda07371a03c17d080f02f4ac4dc1f840b2b40" python-versions = "^3.7" [metadata.files] @@ -2295,7 +2295,7 @@ flake8-polyfill = [ {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"}, ] flake8-rst-docstrings = [ - {file = "flake8-rst-docstrings-0.0.13.tar.gz", hash = "sha256:b1b619d81d879b874533973ac04ee5d823fdbe8c9f3701bfe802bb41813997b4"}, + {file = "flake8-rst-docstrings-0.0.14.tar.gz", hash = "sha256:8f8bcb18f1408b506dd8ba2c99af3eac6128f6911d4bf6ff874b94caa70182a2"}, ] gitdb = [ {file = "gitdb-4.0.5-py3-none-any.whl", hash = "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac"}, @@ -2463,6 +2463,8 @@ pillow = [ {file = "Pillow-7.2.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:5e51ee2b8114def244384eda1c82b10e307ad9778dac5c83fb0943775a653cd8"}, {file = "Pillow-7.2.0-cp38-cp38-win32.whl", hash = "sha256:725aa6cfc66ce2857d585f06e9519a1cc0ef6d13f186ff3447ab6dff0a09bc7f"}, {file = "Pillow-7.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:a060cf8aa332052df2158e5a119303965be92c3da6f2d93b6878f0ebca80b2f6"}, + {file = "Pillow-7.2.0-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:9c87ef410a58dd54b92424ffd7e28fd2ec65d2f7fc02b76f5e9b2067e355ebf6"}, + {file = "Pillow-7.2.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:e901964262a56d9ea3c2693df68bc9860b8bdda2b04768821e4c44ae797de117"}, {file = "Pillow-7.2.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:25930fadde8019f374400f7986e8404c8b781ce519da27792cbe46eabec00c4d"}, {file = "Pillow-7.2.0.tar.gz", hash = "sha256:97f9e7953a77d5a70f49b9a48da7776dc51e9b738151b22dacf101641594a626"}, ] @@ -2504,25 +2506,30 @@ pycryptodome = [ {file = "pycryptodome-3.9.8-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:6276478ada411aca97c0d5104916354b3d740d368407912722bd4d11aa9ee4c2"}, {file = "pycryptodome-3.9.8-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:54bdedd28476dea8a3cd86cb67c0df1f0e3d71cae8022354b0f879c41a3d27b2"}, {file = "pycryptodome-3.9.8-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f521178e5a991ffd04182ed08f552daca1affcb826aeda0e1945cd989a9d4345"}, + {file = "pycryptodome-3.9.8-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:f2e045224074d5664dc9cbabbf4f4d4d46f1ee90f24780e3a9a668fd096ff17f"}, {file = "pycryptodome-3.9.8-cp35-cp35m-win32.whl", hash = "sha256:a207231a52426de3ff20f5608f0687261a3329d97a036c51f7d4c606a6f30c23"}, {file = "pycryptodome-3.9.8-cp35-cp35m-win_amd64.whl", hash = "sha256:2b998dc45ef5f4e5cf5248a6edfcd8d8e9fb5e35df8e4259b13a1b10eda7b16b"}, {file = "pycryptodome-3.9.8-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:03d5cca8618620f45fd40f827423f82b86b3a202c8d44108601b0f5f56b04299"}, {file = "pycryptodome-3.9.8-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:f78a68c2c820e4731e510a2df3eef0322f24fde1781ced970bf497b6c7d92982"}, {file = "pycryptodome-3.9.8-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:132a56abba24e2e06a479d8e5db7a48271a73a215f605017bbd476d31f8e71c1"}, + {file = "pycryptodome-3.9.8-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:cecbf67e81d6144a50dc615629772859463b2e4f815d0c082fa421db362f040e"}, {file = "pycryptodome-3.9.8-cp36-cp36m-win32.whl", hash = "sha256:67dcad1b8b201308586a8ca2ffe89df1e4f731d5a4cdd0610cc4ea790351c739"}, {file = "pycryptodome-3.9.8-cp36-cp36m-win_amd64.whl", hash = "sha256:b56638d58a3a4be13229c6a815cd448f9e3ce40c00880a5398471b42ee86f50e"}, {file = "pycryptodome-3.9.8-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:bec2bcdf7c9ce7f04d718e51887f3b05dc5c1cfaf5d2c2e9065ecddd1b2f6c9a"}, {file = "pycryptodome-3.9.8-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:abc2e126c9490e58a36a0f83516479e781d83adfb134576a5cbe5c6af2a3e93c"}, {file = "pycryptodome-3.9.8-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ef39c98d9b8c0736d91937d193653e47c3b19ddf4fc3bccdc5e09aaa4b0c5d21"}, + {file = "pycryptodome-3.9.8-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:87006cf0d81505408f1ae4f55cf8a5d95a8e029a4793360720ae17c6500f7ecc"}, {file = "pycryptodome-3.9.8-cp37-cp37m-win32.whl", hash = "sha256:4350a42028240c344ee855f032c7d4ad6ff4f813bfbe7121547b7dc579ecc876"}, {file = "pycryptodome-3.9.8-cp37-cp37m-win_amd64.whl", hash = "sha256:c8bf40cf6e281a4378e25846924327e728a887e8bf0ee83b2604a0f4b61692e8"}, {file = "pycryptodome-3.9.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d8074c8448cfd0705dfa71ca333277fce9786d0b9cac75d120545de6253f996a"}, {file = "pycryptodome-3.9.8-cp38-cp38-manylinux1_i686.whl", hash = "sha256:8063a712fba642f78d3c506b0896846601b6de7f5c3d534e388ad0cc07f5a149"}, {file = "pycryptodome-3.9.8-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:dd302b6ae3965afeb5ef1b0d92486f986c0e65183cd7835973f0b593800590e6"}, + {file = "pycryptodome-3.9.8-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:663f8de2b3df2e744d6e1610506e0ea4e213bde906795953c1e82279c169f0a7"}, {file = "pycryptodome-3.9.8-cp38-cp38-win32.whl", hash = "sha256:02e51e1d5828d58f154896ddfd003e2e7584869c275e5acbe290443575370fba"}, {file = "pycryptodome-3.9.8-cp38-cp38-win_amd64.whl", hash = "sha256:55eb61aca2c883db770999f50d091ff7c14016f2769ad7bca3d9b75d1d7c1b68"}, {file = "pycryptodome-3.9.8-cp39-cp39-manylinux1_i686.whl", hash = "sha256:39ef9fb52d6ec7728fce1f1693cb99d60ce302aeebd59bcedea70ca3203fda60"}, {file = "pycryptodome-3.9.8-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:de6e1cd75677423ff64712c337521e62e3a7a4fc84caabbd93207752e831a85a"}, + {file = "pycryptodome-3.9.8-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:9f62d21bc693f3d7d444f17ed2ad7a913b4c37c15cd807895d013c39c0517dfd"}, {file = "pycryptodome-3.9.8.tar.gz", hash = "sha256:0e24171cf01021bc5dc17d6a9d4f33a048f09d62cc3f62541e95ef104588bda4"}, ] pydocstyle = [ diff --git a/pyproject.toml b/pyproject.toml index 2a341597ebd03a855ebb772111a6005b8fb75cc1..f841e62c033f77cdf3751c10ab24d8afc7f1f44b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ flake8-mypy = "^17.8.0" flake8-bandit = "^2.1.2" flake8-builtins = "^1.4.1" flake8-docstrings = "^1.5.0" -flake8-rst-docstrings = "^0.0.13" +flake8-rst-docstrings = "^0.0.14" black = "^19.10b0" flake8-black = "^0.2.0" isort = "^5.0.0"