Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • AlekSIS/official/AlekSIS-App-Alsijil
  • sunweaver/AlekSIS-App-Alsijil
  • 8tincsoVluke/AlekSIS-App-Alsijil
  • perfreicpo/AlekSIS-App-Alsijil
  • noifobarep/AlekSIS-App-Alsijil
  • 7ingannisdo/AlekSIS-App-Alsijil
  • unmruntartpa/AlekSIS-App-Alsijil
  • balrorebta/AlekSIS-App-Alsijil
  • comliFdifwa/AlekSIS-App-Alsijil
  • 3ranaadza/AlekSIS-App-Alsijil
10 results
Show changes
Commits on Source (159)
Showing
with 2306 additions and 1749 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,6 +9,76 @@ and this project adheres to `Semantic Versioning`_.
Unreleased
----------
Added
~~~~~
* Integrate seating plans in lesson overview
Fixed
~~~~~
* The week overview page was not refreshed when a new week was selected in the dropdown.
Added
~~~~~
* Excuse types can now be marked as `Count as absent`, which they are per default. If not, they aren't counted in the overviews.
`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
----------------------
Fixed
~~~~~
* Fix problems with displaying dates for events in the week and lesson view.
* Unique constraint on lesson documentations and personal notes did not work and caused racey duplicates.
`2.0rc5`_ - 2021-08-12
----------------------
Fixed
~~~~~
......@@ -180,3 +250,8 @@ Fixed
.. _2.0rc2: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.0rc2
.. _2.0rc3: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.0rc3
.. _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(
......
......@@ -69,10 +69,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 +180,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 +217,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(
......
......@@ -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.3 on 2021-08-20 12:38
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('alsijil', '0013_fix_uniqueness_per_site'),
]
operations = [
migrations.RemoveConstraint(
model_name='lessondocumentation',
name='unique_documentation_per_object',
),
migrations.AddConstraint(
model_name='lessondocumentation',
constraint=models.UniqueConstraint(fields=('week', 'year', 'lesson_period'), name='unique_documentation_per_lp'),
),
migrations.AddConstraint(
model_name='lessondocumentation',
constraint=models.UniqueConstraint(fields=('week', 'year', 'event'), name='unique_documentation_per_ev'),
),
migrations.AddConstraint(
model_name='lessondocumentation',
constraint=models.UniqueConstraint(fields=('week', 'year', 'extra_lesson'), name='unique_documentation_per_el'),
),
]
# Generated by Django 3.2.4 on 2021-08-29 13:31
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('alsijil', '0014_fix_unique_lesson_documentation'),
]
operations = [
migrations.RemoveConstraint(
model_name='personalnote',
name='unique_personal_note_per_object',
),
migrations.AddConstraint(
model_name='personalnote',
constraint=models.UniqueConstraint(fields=('week', 'year', 'lesson_period', 'person'), name='unique_note_per_lp'),
),
migrations.AddConstraint(
model_name='personalnote',
constraint=models.UniqueConstraint(fields=('week', 'year', 'event', 'person'), name='unique_note_per_ev'),
),
migrations.AddConstraint(
model_name='personalnote',
constraint=models.UniqueConstraint(fields=('week', 'year', 'extra_lesson', 'person'), name='unique_note_per_el'),
),
]
# 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.
This diff is collapsed.