diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5389a72e60aac898a48868c0cb52fe7241fcec60..c5839dcf73864a97c53e0d84a080124cc221fa5c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,11 @@ Changelog `1.0a3`_ -------- +New features +~~~~~~~~~~~~ + +* Allow to register absences and excuses centrally + Bugfixes ~~~~~~~~ diff --git a/biscuit/apps/alsijil/forms.py b/biscuit/apps/alsijil/forms.py index 7912bcf8bccf4e0f4939cb15771010c1ab4ee741..6084cf2bf015b42b937fc20b10c41af3453a8066 100644 --- a/biscuit/apps/alsijil/forms.py +++ b/biscuit/apps/alsijil/forms.py @@ -2,6 +2,7 @@ from django import forms from django.db.models import Count from django.utils.translation import ugettext_lazy as _ from django_select2.forms import Select2Widget +from datetime import datetime from biscuit.apps.chronos.models import Room from biscuit.core.models import Group, Person @@ -47,3 +48,12 @@ class SelectForm(forms.Form): PersonalNoteFormSet = forms.modelformset_factory( PersonalNote, form=PersonalNoteForm, max_num=0, extra=0) + + +class ManageAbsenceForm(forms.Form): + date_start = forms.DateField(label=_('Start date'), widget=forms.SelectDateWidget, initial=datetime.today) + date_end = forms.DateField(label=_('End date'), widget=forms.SelectDateWidget, initial=datetime.today) + starting_lesson = forms.IntegerField(label=_('Starting lesson'), initial=0) + person = forms.ModelChoiceField(label=_('Person'), queryset=Person.objects.all(), widget=Select2Widget) + absent = forms.BooleanField(label=_('Absent'), initial=True) + excused = forms.BooleanField(label=_('Excused'), initial=True) diff --git a/biscuit/apps/alsijil/menus.py b/biscuit/apps/alsijil/menus.py index b5389356179362399cdb1e844eb4ae715943bcb8..6184cbe5d54b5193c0050cd316e5a78b769a484a 100644 --- a/biscuit/apps/alsijil/menus.py +++ b/biscuit/apps/alsijil/menus.py @@ -17,6 +17,11 @@ MENUS = { 'name': _('Current week'), 'url': 'week_view', 'validators': ['menu_generator.validators.is_authenticated'] + }, + { + 'name': _('Manage absence'), + 'url': 'manage_absence', + 'validators': ['menu_generator.validators.is_superuser'] } ] } diff --git a/biscuit/apps/alsijil/templates/alsijil/manage_absence.html b/biscuit/apps/alsijil/templates/alsijil/manage_absence.html new file mode 100644 index 0000000000000000000000000000000000000000..16231893fd5975bbea0953a84fbcf57aea3faf44 --- /dev/null +++ b/biscuit/apps/alsijil/templates/alsijil/manage_absence.html @@ -0,0 +1,29 @@ +{# -*- engine:django -*- #} +{% extends "core/base.html" %} +{% load bootstrap4 i18n static %} + +{% block bootstrap4_extra_head %} + {{ block.super }} + {{ manage_absence_form.media.css }} +{% endblock %} + +{% block bootstrap4_extra_script %} + {{ block.super }} + {{ manage_absence_form.media.js }} +{% endblock %} + +{% block bootstrap4_title %}{% blocktrans%}Manage absence{% endblocktrans %} - {{ block.super }}{% endblock %} + +{% block page_title %}Manage absences{% endblock %} + +{% block content %} + + <form method="post"> + {% csrf_token %} + {% bootstrap_form manage_absence_form %} + <button type="submit" class="btn btn-dark"> + {% blocktrans %}Save{% endblocktrans %} + </button> + </form> + +{% endblock %} diff --git a/biscuit/apps/alsijil/urls.py b/biscuit/apps/alsijil/urls.py index e8d4c6b254273d10a1152239d9de3bc9ba0bc260..97aa3f4b1d251217419ecd3c520972fe67364d1b 100644 --- a/biscuit/apps/alsijil/urls.py +++ b/biscuit/apps/alsijil/urls.py @@ -11,5 +11,7 @@ urlpatterns = [ path('week/<int:year>/<int:week>', views.week_view, name='week_view_by_week'), path('print/group/<int:id_>', views.full_register_group, - name='full_register_group') + name='full_register_group'), + path('absences/new', views.manage_absence, + name='manage_absence'), ] diff --git a/biscuit/apps/alsijil/views.py b/biscuit/apps/alsijil/views.py index 497576ce2a1daab1f4a392e3a404cbc52c8c2057..f18dd9d578ba1cd355fab7579d456e1f2dd3c7fc 100644 --- a/biscuit/apps/alsijil/views.py +++ b/biscuit/apps/alsijil/views.py @@ -1,4 +1,4 @@ -from datetime import date, datetime +from datetime import date, datetime, timedelta from typing import Optional from django.contrib.auth.decorators import login_required @@ -12,8 +12,10 @@ from django.utils.translation import ugettext as _ from biscuit.apps.chronos.models import LessonPeriod from biscuit.apps.chronos.util import CalendarWeek from biscuit.core.models import Group, Person +from biscuit.core.decorators import admin_required +from biscuit.core.util import messages -from .forms import LessonDocumentationForm, PersonalNoteFormSet, SelectForm +from .forms import ManageAbsenceForm, LessonDocumentationForm, PersonalNoteFormSet, SelectForm from .models import LessonDocumentation @@ -202,3 +204,35 @@ def full_register_group(request: HttpRequest, id_: int) -> HttpResponse: context['today'] = date.today() return render(request, 'alsijil/print/full_register.html', context) + + +@admin_required +def manage_absence(request: HttpRequest) -> HttpResponse: + context = {} + + manage_absence_form = ManageAbsenceForm(request.POST or None) + + if request.method == 'POST': + if manage_absence_form.is_valid(): + # Get data from form + person = manage_absence_form.cleaned_data['person'] + start_date = manage_absence_form.cleaned_data['date_start'] + end_date = manage_absence_form.cleaned_data['date_end'] + starting_lesson = manage_absence_form.cleaned_data['starting_lesson'] + absent = manage_absence_form.cleaned_data['absent'] + excused = manage_absence_form.cleaned_data['excused'] + + # Mark person as absent + delta = end_date - start_date + for i in range(delta.days+1): + starting_period = starting_lesson if i == 0 else 0 + day = start_date + timedelta(days=1) + person.mark_absent(day, starting_period=starting_period, absent=absent, excused=excused) + person.save() + + messages.success(request, _('The absence has been saved.')) + return redirect('index') + + context['manage_absence_form'] = manage_absence_form + + return render(request, 'alsijil/manage_absence.html', context)