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

Merge branch 'master' into 174-instructions-can-be-linked-to-a-document-as-remarks-by-the-group

parents ca376d51 b2e79686
No related branches found
No related tags found
1 merge request!215Draft: Resolve "Instructions can be linked to a document as remarks by the group"
Pipeline #72899 failed
Showing
with 4916 additions and 1434 deletions
......@@ -59,3 +59,5 @@ docs/_build/
.coverage
.mypy_cache/
htmlcov/
poetry.lock
include:
- project: "AlekSIS/official/AlekSIS"
file: /ci/general.yml
- project: "AlekSIS/official/AlekSIS"
file: /ci/prepare/lock.yml
- project: "AlekSIS/official/AlekSIS"
file: /ci/test/test.yml
- project: "AlekSIS/official/AlekSIS"
......@@ -11,3 +13,5 @@ include:
file: /ci/build/dist.yml
- project: "AlekSIS/official/AlekSIS"
file: /ci/publish/pypi.yml
- project: "AlekSIS/official/AlekSIS"
file: /ci/docker/image.yml
......@@ -9,11 +9,61 @@ and this project adheres to `Semantic Versioning`_.
Unreleased
----------
Added
~~~~~
* Integrate seating plans in lesson overview
* Add option to set LessonDocumentation data for all lessons in one week at once.
* Excuse types can now be marked as `Count as absent`, which they are per default. If not, they aren't counted in the overviews.
* Add Ukrainian locale (contributed by Sergiy Gorichenko from Fre(i)e Software GmbH).
Fixed
~~~~~
* The week overview page was not refreshed when a new week was selected in the dropdown.
`2.0.1`_ - 2022-02-12
---------------------
Fixed
~~~~~
* Status icon in single-lesson view showed 'Missing data' although the data were complete.
* The personal note tab of a lesson was not well usable on mobile devices.
`2.0`_ - 2022-02-06
------------------
Changed
~~~~~~~
* Use start date of current SchoolTerm as default value for PersonalNote filter in overview.
Fixed
~~~~~
* Events without groups caused an error when not accessed through the week view.
`2.0rc7`_ - 2021-12-25
---------------------
Changed
~~~~~~~
* Optimize view for one register object ("lesson view") for mobile and tablet devices.
* Optimize view for lessons of a week ("week view") for mobile and tablet devices.
* German translations were updated.
* Link to personal notes in the personal overview.
Fixed
~~~~~
* Translate table columns and filter button on person overview page.
* Show correct status icon for events.
* Subjects in full register printout were struck through although they
hadn't changed.
* Table with all register objects didn't work with extra lessons.
* Add missing definitions of some permissions so they can be assigned.
`2.0rc6`_ - 2021-08-25
----------------------
......@@ -200,3 +250,6 @@ Fixed
.. _2.0rc4: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.0rc4
.. _2.0rc5: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.0rc5
.. _2.0rc6: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.0rc6
.. _2.0rc7: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.0rc7
.. _2.0: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.0
.. _2.0.1: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.0.1
ARG APPS="AlekSIS-App-Alsijil"
FROM registry.edugit.org/aleksis/official/aleksis-core:master
......@@ -4,7 +4,7 @@ AlekSIS (School Information System) — App كتاب السجل (class regis
AlekSIS
-------
This is an application for use with the `AlekSIS`_ platform.
This is an application for use with the `AlekSIS®`_ platform.
Features
--------
......@@ -22,6 +22,9 @@ This AlekSIS app currently provides the following features for managing digital
* Show all owned groups of the current person
* Show all students of the current person
* Show filterable (week) overview for lesson documentations and personal/group notes
* Manage absence of persons
* Show overview of all students with statistics
Licence
-------
......@@ -44,5 +47,13 @@ full licence text or on the `European Union Public Licence`_ website
https://joinup.ec.europa.eu/collection/eupl/guidelines-users-and-developers
(including all other official language versions).
.. _AlekSIS: https://edugit.org/AlekSIS/Official/AlekSIS
Trademark
---------
AlekSIS® is a registered trademark of the AlekSIS open source project, represented
by Teckids e.V. Please refer to the `trademark policy`_ for hints on using the trademark
AlekSIS®.
.. _AlekSIS®: https://edugit.org/AlekSIS/Official/AlekSIS
.. _European Union Public Licence: https://eupl.eu/
.. _trademark policy: https://aleksis.org/pages/about
......@@ -3,6 +3,8 @@ from django.utils.translation import gettext as _
from django_filters import CharFilter, DateFilter, FilterSet
from material import Layout, Row
from aleksis.core.models import SchoolTerm
from .models import PersonalNote
......@@ -11,8 +13,20 @@ class PersonalNoteFilter(FilterSet):
day_end = DateFilter(lookup_expr="lte", label=_("Before"))
subject = CharFilter(lookup_expr="icontains", label=_("Subject"))
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def __init__(self, data=None, *args, **kwargs):
if data is not None:
data = data.copy()
current_school_term = SchoolTerm.current
if not data.get("day_start") and current_school_term:
data["day_start"] = current_school_term.date_start
for name, f in self.base_filters.items():
initial = f.extra.get("initial")
if not data.get(name) and initial:
data[name] = initial
super().__init__(data, *args, **kwargs)
self.form.fields["late__lt"].label = _("Tardiness is lower than")
self.form.fields["late__gt"].label = _("Tardiness is bigger than")
self.form.layout = Layout(
......
......@@ -13,7 +13,7 @@ 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 Subject, TimePeriod
from aleksis.apps.chronos.models import LessonPeriod, Subject, TimePeriod
from aleksis.core.forms import ActionForm, ListActionForm
from aleksis.core.models import Group, Person, SchoolTerm
from aleksis.core.util.core_helpers import get_site_preferences
......@@ -45,6 +45,30 @@ class LessonDocumentationForm(forms.ModelForm):
super().__init__(*args, **kwargs)
self.fields["homework"].label = _("Homework for the next lesson")
if (
self.instance.lesson_period
and get_site_preferences()["alsijil__allow_carry_over_same_week"]
):
self.fields["carry_over_week"] = forms.BooleanField(
label=_("Carry over data to all other lessons with the same subject in this week"),
initial=True,
required=False,
)
def save(self, **kwargs):
lesson_documentation = super(LessonDocumentationForm, self).save(commit=True)
if (
self.cleaned_data["carry_over_week"]
and (
lesson_documentation.topic
or lesson_documentation.homework
or lesson_documentation.group_note
)
and lesson_documentation.lesson_period
):
lesson_documentation.carry_over_data(
LessonPeriod.objects.filter(lesson=lesson_documentation.lesson_period.lesson)
)
class PersonalNoteForm(forms.ModelForm):
......@@ -69,10 +93,16 @@ class SelectForm(forms.Form):
layout = Layout(Row("group", "teacher"))
group = forms.ModelChoiceField(
queryset=None, label=_("Group"), required=False, widget=Select2Widget,
queryset=None,
label=_("Group"),
required=False,
widget=Select2Widget,
)
teacher = forms.ModelChoiceField(
queryset=None, label=_("Teacher"), required=False, widget=Select2Widget,
queryset=None,
label=_("Teacher"),
required=False,
widget=Select2Widget,
)
def clean(self) -> dict:
......@@ -174,11 +204,11 @@ class ExtraMarkForm(forms.ModelForm):
class ExcuseTypeForm(forms.ModelForm):
layout = Layout("short_name", "name")
layout = Layout("short_name", "name", "count_as_absent")
class Meta:
model = ExcuseType
fields = ["short_name", "name"]
fields = ["short_name", "name", "count_as_absent"]
class PersonOverviewForm(ActionForm):
......@@ -211,7 +241,10 @@ class AssignGroupRoleForm(forms.ModelForm):
widget=ModelSelect2MultipleWidget(
model=Group,
search_fields=["name__icontains", "short_name__icontains"],
attrs={"data-minimum-input-length": 0, "class": "browser-default",},
attrs={
"data-minimum-input-length": 0,
"class": "browser-default",
},
),
)
person = forms.ModelChoiceField(
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -68,7 +68,8 @@ class RegisterObjectRelatedQuerySet(QuerySet):
When(day__isnull=True, then="event__date_start"),
),
day_end=Case(
When(day__isnull=False, then="day"), When(day__isnull=True, then="event__date_end"),
When(day__isnull=False, then="day"),
When(day__isnull=True, then="event__date_end"),
),
)
......@@ -76,8 +77,14 @@ class RegisterObjectRelatedQuerySet(QuerySet):
"""Annotate lesson documentations with the subjects."""
return self.annotate(
subject=Case(
When(lesson_period__isnull=False, then="lesson_period__lesson__subject__name",),
When(extra_lesson__isnull=False, then="extra_lesson__subject__name",),
When(
lesson_period__isnull=False,
then="lesson_period__lesson__subject__name",
),
When(
extra_lesson__isnull=False,
then="extra_lesson__subject__name",
),
default=Value(_("Event")),
)
)
......@@ -142,7 +149,12 @@ class GroupRoleQuerySet(QuerySet):
qs = GroupRoleAssignment.objects.on_day(time_ref)
qs = qs.for_groups(groups).distinct()
return self.prefetch_related(Prefetch("assignments", queryset=qs,))
return self.prefetch_related(
Prefetch(
"assignments",
queryset=qs,
)
)
class GroupRoleAssignmentManager(CurrentSiteManagerWithoutMigrations):
......
# Generated by Django 3.2.12 on 2022-03-20 10:12
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('alsijil', '0015_fix_unique_personal_note'),
]
operations = [
migrations.AddField(
model_name='excusetype',
name='count_as_absent',
field=models.BooleanField(default=True, help_text="If checked, this excuse type will be counted as a missed lesson. If not checked, it won't show up in the absence report.", verbose_name='Count as missed lesson'),
),
]
......@@ -105,7 +105,11 @@ def mark_absent(
.prefetch_related(None)
.update_or_create(
person=self,
defaults={"absent": absent, "excused": excused, "excuse_type": excuse_type,},
defaults={
"absent": absent,
"excused": excused,
"excuse_type": excuse_type,
},
**q_attrs,
)
)
......@@ -150,12 +154,17 @@ def get_personal_notes(
no_personal_notes=~Exists(PersonalNote.objects.filter(person__pk=OuterRef("pk"), **q_attrs))
).filter(
member_of__in=Group.objects.filter(pk__in=self.get_groups().all()),
is_active=True,
no_personal_notes=True,
)
# Create all missing personal notes
new_personal_notes = [PersonalNote(person=person, **q_attrs,) for person in missing_persons]
new_personal_notes = [
PersonalNote(
person=person,
**q_attrs,
)
for person in missing_persons
]
PersonalNote.objects.bulk_create(new_personal_notes)
for personal_note in new_personal_notes:
......@@ -177,10 +186,12 @@ ExtraLesson.method(get_personal_notes)
# 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"),
"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"),
"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"))
......@@ -194,6 +205,7 @@ Group.add_permission("view_full_register_group", _("Can view full register of a
Group.add_permission(
"register_absence_group", _("Can register an absence for all members of a group")
)
Group.add_permission("assign_grouprole", _("Can assign a group role for this group"))
Person.add_permission("register_absence_person", _("Can register an absence for a person"))
......@@ -206,7 +218,8 @@ def get_lesson_documentation(
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(),
lambda d: d.week == week.week and d.year == week.year,
self.documentations.all(),
)
try:
return next(doc_filter)
......@@ -409,9 +422,19 @@ def generate_person_list_with_class_register_statistics(
)
).annotate(
absences_count=Count(
"filtered_personal_notes", filter=Q(filtered_personal_notes__absent=True),
"filtered_personal_notes",
filter=Q(filtered_personal_notes__absent=True)
& ~Q(filtered_personal_notes__excuse_type__count_as_absent=False),
),
excused=Count(
"filtered_personal_notes",
filter=Q(
filtered_personal_notes__absent=True,
filtered_personal_notes__excused=True,
)
& ~Q(filtered_personal_notes__excuse_type__count_as_absent=False),
),
excused_without_excuse_type=Count(
"filtered_personal_notes",
filter=Q(
filtered_personal_notes__absent=True,
......@@ -425,7 +448,8 @@ def generate_person_list_with_class_register_statistics(
),
tardiness=Sum("filtered_personal_notes__late"),
tardiness_count=Count(
"filtered_personal_notes", filter=Q(filtered_personal_notes__late__gt=0),
"filtered_personal_notes",
filter=Q(filtered_personal_notes__late__gt=0),
),
)
......
This diff is collapsed.
......@@ -46,7 +46,7 @@ class EditLessonDocumentationAsOriginalTeacher(BooleanPreference):
@site_preferences_registry.register
class CarryOverDataToNextPeriods(BooleanPreference):
section = alsijil
name = "carry_over"
name = "carry_over_next_periods"
default = True
verbose_name = _(
"Carry over data from first lesson period to the "
......@@ -55,6 +55,20 @@ class CarryOverDataToNextPeriods(BooleanPreference):
help_text = _("This will carry over data only if the data in the following periods are empty.")
@site_preferences_registry.register
class AllowCarryOverLessonDocumentationToCurrentWeek(BooleanPreference):
section = alsijil
name = "allow_carry_over_same_week"
default = False
verbose_name = _(
"Allow carrying over data from any lesson period to all other lesson \
periods with the same lesson and in the same week"
)
help_text = _(
"This will carry over data only if the data in the aforementioned periods are empty."
)
@site_preferences_registry.register
class CarryOverPersonalNotesToNextPeriods(BooleanPreference):
section = alsijil
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment