Skip to content
Snippets Groups Projects
Verified Commit ca376d51 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 721c03d3 564895ee
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 #38611 failed
Showing
with 794 additions and 608 deletions
......@@ -56,3 +56,6 @@ docs/_build/
# Test
.tox/
.coverage
.mypy_cache/
htmlcov/
include:
- project: "AlekSIS/official/AlekSIS"
file: /ci/general.yml
# - project: "AlekSIS/official/AlekSIS"
# file: /ci/test/test.yml
- project: "AlekSIS/official/AlekSIS"
file: /ci/test/test.yml
- project: "AlekSIS/official/AlekSIS"
file: /ci/test/lint.yml
- project: "AlekSIS/official/AlekSIS"
......
......@@ -6,6 +6,33 @@ All notable changes to this project will be documented in this file.
The format is based on `Keep a Changelog`_,
and this project adheres to `Semantic Versioning`_.
Unreleased
----------
Fixed
~~~~~
* Translate table columns and filter button on person overview page.
* Show correct status icon for events.
`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
~~~~~
* The _Delete personal note_ action didn't work due to wrong usage of ``bulk_update``.
* Groups and persons were shown multiple times in some forms due to filtering by permissions.
`2.0rc4`_ - 2021-08-01
----------------------
......@@ -171,3 +198,5 @@ 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
......@@ -40,7 +40,9 @@ def delete_personal_note(modeladmin, request, queryset):
for personal_note in queryset:
personal_note.reset_values()
notes.append(personal_note)
PersonalNote.objects.bulk_update(notes)
PersonalNote.objects.bulk_update(
notes, fields=["absent", "excused", "late", "excuse_type", "remarks"]
)
delete_personal_note.short_description = _("Delete")
......
......@@ -256,11 +256,13 @@ class AssignGroupRoleForm(forms.ModelForm):
)
else:
persons = persons.filter(member_of__owners=self.request.user.person)
self.fields["person"].queryset = persons
self.fields["person"].queryset = persons.distinct()
if "groups" not in initial:
groups = Group.objects.for_current_school_term_or_all().filter(
owners=self.request.user.person
groups = (
Group.objects.for_current_school_term_or_all()
.filter(owners=self.request.user.person)
.distinct()
)
self.fields["groups"].queryset = groups
......@@ -332,7 +334,7 @@ class FilterRegisterObjectForm(forms.Form):
| Q(lessons__lesson_periods__substitutions__teachers=person)
| Q(events__teachers=person)
| Q(extra_lessons__teachers=person)
)
).distinct()
elif not for_person:
groups = Group.objects.all()
self.fields["group"].queryset = groups
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
# 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'),
),
]
......@@ -288,8 +288,13 @@ class PersonalNote(RegisterObjectRelatedMixin, ExtensibleModel):
check=lesson_related_constraint_q, name="one_relation_only_personal_note"
),
models.UniqueConstraint(
fields=("lesson_period", "week", "year", "event", "extra_lesson"),
name="unique_personal_note_per_object",
fields=("week", "year", "lesson_period", "person"), name="unique_note_per_lp",
),
models.UniqueConstraint(
fields=("week", "year", "event", "person"), name="unique_note_per_ev",
),
models.UniqueConstraint(
fields=("week", "year", "extra_lesson", "person"), name="unique_note_per_el",
),
]
......@@ -378,8 +383,13 @@ class LessonDocumentation(RegisterObjectRelatedMixin, ExtensibleModel):
check=lesson_related_constraint_q, name="one_relation_only_lesson_documentation",
),
models.UniqueConstraint(
fields=("lesson_period", "week", "year", "event", "extra_lesson"),
name="unique_documentation_per_object",
fields=("week", "year", "lesson_period"), name="unique_documentation_per_lp",
),
models.UniqueConstraint(
fields=("week", "year", "event"), name="unique_documentation_per_ev",
),
models.UniqueConstraint(
fields=("week", "year", "extra_lesson"), name="unique_documentation_per_el",
),
]
......
......@@ -105,10 +105,10 @@ class PersonalNoteTable(tables.Table):
order_by=A("order_teachers"),
)
subject = tables.Column(verbose_name=_("Subject"), accessor=A("subject"))
absent = tables.Column()
late = tables.Column()
absent = tables.Column(verbose_name=_("Absent"))
late = tables.Column(verbose_name=_("Tardiness"))
excused = tables.Column(verbose_name=_("Excuse"))
extra_marks = tables.Column(verbose_name="Extra marks", accessor=A("extra_marks__all"))
extra_marks = tables.Column(verbose_name=_("Extra marks"), accessor=A("extra_marks__all"))
def render_groups(self, value, record):
if isinstance(record.register_object, LessonPeriod):
......@@ -126,7 +126,7 @@ class PersonalNoteTable(tables.Table):
return (
render_to_string(
"components/materialize-chips.html",
dict(content="Absent", classes="red white-text"),
dict(content=_("Absent"), classes="red white-text"),
)
if value
else ""
......
......@@ -179,12 +179,11 @@
{% with absences=prev_lesson.get_absences tardinesses=prev_lesson.get_tardinesses extra_marks=prev_lesson.get_extra_marks %}
{% has_perm "alsijil.view_lessondocumentation_rule" 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">
{% blocktrans %}Overview: Previous lesson{% endblocktrans %} ({{ prev_date }},
{% blocktrans %}Overview: Previous lesson{% endblocktrans %} ({{ prev_doc.date_formatted }},
{% blocktrans with period=prev_lesson.period.period %}{{ period }}. period{% endblocktrans %})
</span>
......
......@@ -88,7 +88,7 @@
{% if can_mark_all_as_excused %} medium-high-right {% endif %}"
data-target="filter-modal"
type="button">
Filter results ({{ num_filters }})<i class="material-icons right">filter_alt</i>
{% trans "Filter results" %} ({{ num_filters }})<i class="material-icons right">filter_alt</i>
</button>
</div>
<form action="" method="post" class="">
......
......@@ -353,10 +353,9 @@
{% for note in person.personal_notes %}
<blockquote>
{{ note.remarks }}
{% weekday_to_date week note.register_object.period.weekday as note_date %}
<em class="right">
<a href="{{ note.register_object.alsijil_url }}">
{{ note.date }}, {{ note.register_object.get_subject.name }}
{{ note.date_formatted }}, {{ note.register_object.get_subject.name }}
</a>
</em>
</blockquote>
......
from datetime import date, time
import pytest
from aleksis.apps.alsijil.actions import (
delete_personal_note,
mark_as_excuse_type_generator,
mark_as_excused,
mark_as_unexcused,
)
from aleksis.apps.alsijil.models import ExcuseType, PersonalNote
from aleksis.apps.chronos.models import Event, TimePeriod
from aleksis.core.models import Person
pytestmark = pytest.mark.django_db
def _generate_event(day: date):
period_from = TimePeriod.objects.create(
weekday=0, period=1, time_start=time(10, 00), time_end=time(11, 00)
)
period_to = TimePeriod.objects.create(
weekday=0, period=2, time_start=time(11, 00), time_end=time(12, 00)
)
event = Event.objects.create(
date_start=day, date_end=day, period_from=period_from, period_to=period_to
)
return event
def _prepare_notes():
"""Create some minimal personal notes."""
person, __ = Person.objects.get_or_create(first_name="Jane", last_name="Doe")
excuse_type, __ = ExcuseType.objects.get_or_create(short_name="Foo", name="Fooooooooooooo")
notes = [
PersonalNote(
person=person,
event=_generate_event(date(2021, 10, 1)),
absent=True,
remarks="This is baz.",
),
PersonalNote(person=person, event=_generate_event(date(2021, 11, 1)), absent=True),
PersonalNote(
person=person, event=_generate_event(date(2022, 10, 1)), absent=True, excused=True
),
PersonalNote(
person=person,
event=_generate_event(date(2021, 3, 1)),
absent=True,
excused=True,
excuse_type=excuse_type,
),
PersonalNote(person=person, event=_generate_event(date(2021, 10, 4)), late=10),
PersonalNote(
person=person, event=_generate_event(date(2032, 10, 11)), remarks="Good work!"
),
PersonalNote(person=person, event=_generate_event(date(2032, 10, 11))),
]
PersonalNote.objects.bulk_create(notes)
return notes
def test_mark_as_excused_action():
notes = _prepare_notes()
assert PersonalNote.objects.filter(excused=True).count() == 2
mark_as_excused(None, None, PersonalNote.objects.all())
assert PersonalNote.objects.filter(excused=True).count() == 4
assert PersonalNote.objects.filter(excuse_type=None, excused=True).count() == 4
def test_mark_as_unexcused_action():
notes = _prepare_notes()
assert PersonalNote.objects.filter(excused=True).count() == 2
mark_as_unexcused(None, None, PersonalNote.objects.all())
assert PersonalNote.objects.filter(excused=True).count() == 0
assert PersonalNote.objects.filter(excuse_type=None, excused=True).count() == 0
def test_mark_as_excuse_type_generator_action():
excuse_type, __ = ExcuseType.objects.get_or_create(short_name="Foo", name="Fooooooooooooo")
notes = _prepare_notes()
assert PersonalNote.objects.filter(excused=True).count() == 2
assert PersonalNote.objects.filter(excused=True, excuse_type=excuse_type).count() == 1
mark_as_foo = mark_as_excuse_type_generator(excuse_type=excuse_type)
mark_as_foo(None, None, PersonalNote.objects.all())
assert PersonalNote.objects.filter(excused=True).count() == 4
assert PersonalNote.objects.filter(excuse_type=excuse_type, excused=True).count() == 4
def test_delete_personal_note_action():
notes = _prepare_notes()
assert PersonalNote.objects.not_empty().count() == 6
delete_personal_note(None, None, PersonalNote.objects.all())
assert PersonalNote.objects.not_empty().count() == 0
......@@ -85,7 +85,8 @@ def annotate_documentations(
instances = instances.annotate(
has_documentation=Exists(
LessonDocumentation.objects.filter(
~Q(topic__exact=""), week=wanted_week.week, year=wanted_week.year,
~Q(topic__exact=""),
Q(week=wanted_week.week, year=wanted_week.year) | Q(week=None, year=None),
).filter(**{klass.label_: OuterRef("pk")})
)
)
......
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