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

Fix and improve register absence form to work with excuse types and a to-period.

parent 19ac25fc
No related branches found
No related tags found
1 merge request!84Resolve "Fix register absence form"
Pipeline #3485 passed
......@@ -6,9 +6,10 @@ from django.db.models import Count
from django.utils.translation import gettext_lazy as _
from django_select2.forms import Select2Widget
from material import Layout, Row
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 .models import ExcuseType, ExtraMark, LessonDocumentation, PersonalNote
......@@ -92,22 +93,36 @@ PersonalNoteFormSet = forms.modelformset_factory(
class RegisterAbsenceForm(forms.Form):
layout = Layout(
Row("date_start", "date_end"),
Row("from_period"),
Row("absent", "excused"),
Row("person"),
Row("remarks"),
Fieldset("", "person"),
Fieldset("", Row("date_start", "date_end"), Row("from_period", "to_period")),
Fieldset("", Row("absent", "excused"), Row("excuse_type"), Row("remarks")),
)
date_start = forms.DateField(label=_("Start date"), initial=datetime.today)
date_end = forms.DateField(label=_("End date"), initial=datetime.today)
from_period = forms.IntegerField(label=_("From period"), initial=0, min_value=0)
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(
label=_("Excuse type"),
queryset=ExcuseType.objects.all(),
widget=Select2Widget,
required=False,
)
remarks = forms.CharField(label=_("Remarks"), max_length=30, required=False)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
period_choices = TimePeriod.period_choices
self.fields["from_period"].choices = period_choices
self.fields["to_period"].choices = period_choices
self.fields["from_period"].initial = TimePeriod.period_min
self.fields["to_period"].initial = TimePeriod.period_max
class ExtraMarkForm(forms.ModelForm):
layout = Layout("short_name", "name")
......
......@@ -20,6 +20,7 @@ def mark_absent(
excused: bool = False,
excuse_type: Optional[ExcuseType] = None,
remarks: str = "",
to_period: Optional[int] = None,
):
"""Mark a person absent for all lessons in a day, optionally starting with a selected period number.
......@@ -39,6 +40,9 @@ def mark_absent(
period__period__gte=from_period
)
if to_period:
lesson_periods = lesson_periods.filter(period__period__lte=to_period)
# Create and update all personal notes for the discovered lesson periods
for lesson_period in lesson_periods:
personal_note, created = PersonalNote.objects.update_or_create(
......
......@@ -2,8 +2,8 @@
{% extends "core/base.html" %}
{% load material_form i18n static %}
{% block browser_title %}{% blocktrans %}Manage absence{% endblocktrans %}{% endblock %}
{% block page_title %}{% blocktrans %}Manage absence{% endblocktrans %}{% endblock %}
{% block browser_title %}{% blocktrans %}Register absence{% endblocktrans %}{% endblock %}
{% block page_title %}{% blocktrans %}Register absence{% endblocktrans %}{% endblock %}
{% block content %}
......@@ -13,4 +13,12 @@
{% include "core/partials/save_button.html" %}
</form>
<script>
$(document).ready(function () {
$("#id_date_start").change(function () {
$("#id_date_end").val($("#id_date_start").val());
$("#id_date_end").change();
});
});
</script>
{% endblock %}
......@@ -14,7 +14,7 @@ from reversion.views import RevisionMixin
from rules.contrib.views import PermissionRequiredMixin
from aleksis.apps.chronos.managers import TimetableType
from aleksis.apps.chronos.models import LessonPeriod
from aleksis.apps.chronos.models import LessonPeriod, 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
......@@ -470,19 +470,33 @@ def register_absence(request: HttpRequest) -> HttpResponse:
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 = from_period if i == 0 else 0
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, absent, excused, remarks)
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("index")
return redirect("register_absence")
context["register_absence_form"] = register_absence_form
......
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