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

Merge branch 'master' into...

Merge branch 'master' into 114-lesson-overview-buttons-for-switching-to-next-previous-lesson-of-the-currently-logged-in-person
parents e5332b2f 533d0b97
No related branches found
No related tags found
1 merge request!98Resolve "[Lesson overview] Buttons for switching to next/previous lesson of the currently logged in person"
Pipeline #4194 failed
...@@ -119,15 +119,11 @@ PersonalNoteFormSet = forms.modelformset_factory( ...@@ -119,15 +119,11 @@ PersonalNoteFormSet = forms.modelformset_factory(
class RegisterAbsenceForm(forms.Form): class RegisterAbsenceForm(forms.Form):
layout = Layout( layout = Layout(
Fieldset("", "person"),
Fieldset("", Row("date_start", "date_end"), Row("from_period", "to_period")), Fieldset("", Row("date_start", "date_end"), Row("from_period", "to_period")),
Fieldset("", Row("absent", "excused"), Row("excuse_type"), Row("remarks")), Fieldset("", Row("absent", "excused"), Row("excuse_type"), Row("remarks")),
) )
date_start = forms.DateField(label=_("Start date"), initial=datetime.today) date_start = forms.DateField(label=_("Start date"), initial=datetime.today)
date_end = forms.DateField(label=_("End date"), initial=datetime.today) date_end = forms.DateField(label=_("End date"), initial=datetime.today)
person = forms.ModelChoiceField(
label=_("Person"), queryset=None, widget=Select2Widget
)
from_period = forms.ChoiceField(label=_("Start period")) from_period = forms.ChoiceField(label=_("Start period"))
to_period = forms.ChoiceField(label=_("End period")) to_period = forms.ChoiceField(label=_("End period"))
absent = forms.BooleanField(label=_("Absent"), initial=True, required=False) absent = forms.BooleanField(label=_("Absent"), initial=True, required=False)
...@@ -145,37 +141,6 @@ class RegisterAbsenceForm(forms.Form): ...@@ -145,37 +141,6 @@ class RegisterAbsenceForm(forms.Form):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
period_choices = TimePeriod.period_choices period_choices = TimePeriod.period_choices
# Filter selectable persons by permissions
if check_global_permission(self.request.user, "alsijil.register_absence"):
# Global permission, user can register absences for all persons
self.fields["person"].queryset = Person.objects.all()
else:
# 1) All persons the user is allowed to register an absence for by object permissions
# 2) All persons the user is the primary group owner
# 3) All persons the user is allowed to register an absence for by object permissions of the person's group
persons_qs = (
get_objects_for_user(
self.request.user, "core.register_absence_person", Person
)
.union(
Person.objects.filter(
primary_group__owners=self.request.user.person
)
)
.union(
Person.objects.filter(
member_of__in=get_objects_for_user(
self.request.user, "core.register_absence_group", Group
)
)
)
)
# Flatten query by getting all pks and filter persons
self.fields["person"].queryset = Person.objects.filter(
pk__in=list(persons_qs.values_list("pk", flat=True))
)
self.fields["from_period"].choices = period_choices self.fields["from_period"].choices = period_choices
self.fields["to_period"].choices = period_choices self.fields["to_period"].choices = period_choices
self.fields["from_period"].initial = TimePeriod.period_min self.fields["from_period"].initial = TimePeriod.period_min
......
...@@ -67,17 +67,6 @@ MENUS = { ...@@ -67,17 +67,6 @@ MENUS = {
), ),
], ],
}, },
{
"name": _("Register absence"),
"url": "register_absence",
"icon": "rate_review",
"validators": [
(
"aleksis.core.util.predicates.permission_validator",
"alsijil.view_register_absence",
),
],
},
{ {
"name": _("Excuse types"), "name": _("Excuse types"),
"url": "excuse_types", "url": "excuse_types",
......
...@@ -113,12 +113,6 @@ view_week_personal_notes_predicate = has_person & ( ...@@ -113,12 +113,6 @@ view_week_personal_notes_predicate = has_person & (
) )
add_perm("alsijil.view_week_personalnote", view_week_personal_notes_predicate) add_perm("alsijil.view_week_personalnote", view_week_personal_notes_predicate)
# View register absence page
view_register_absence_predicate = has_person & (
has_global_perm("alsijil.register_absence") | has_any_object_absence
)
add_perm("alsijil.view_register_absence", view_register_absence_predicate)
# Register absence # Register absence
register_absence_predicate = has_person & ( register_absence_predicate = has_person & (
( (
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
{% block page_title %}{% blocktrans %}Register absence{% endblocktrans %}{% endblock %} {% block page_title %}{% blocktrans %}Register absence{% endblocktrans %}{% endblock %}
{% block content %} {% block content %}
<h6>{% trans "Person" %}: {{ person }}</h6>
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
......
...@@ -23,6 +23,13 @@ ...@@ -23,6 +23,13 @@
{% block content %} {% block content %}
{% has_perm "alsijil.edit_person_overview_personalnote" user person as can_mark_all_as_excused %} {% has_perm "alsijil.edit_person_overview_personalnote" user person as can_mark_all_as_excused %}
{% has_perm "alsijil.register_absence" user person as can_register_absence %}
{% if can_register_absence %}
<a class="btn primary-color waves-effect waves-light" href="{% url "register_absence" person.pk %}">
<i class="material-icons left">rate_review</i>
{% trans "Register absence" %}
</a>
{% endif %}
<div class="row"> <div class="row">
<div class="col s12 m12 l6"> <div class="col s12 m12 l6">
......
...@@ -249,6 +249,13 @@ ...@@ -249,6 +249,13 @@
{% else %} {% else %}
{{ person.person.full_name }} {{ person.person.full_name }}
{% endif %} {% endif %}
{% has_perm "alsijil.register_absence" user person.person as can_register_absence %}
{% if can_register_absence %}
<a class="btn primary-color waves-effect waves-light right" href="{% url "register_absence" person.person.pk %}">
<i class="material-icons left">rate_review</i>
{% trans "Register absence" %}
</a>
{% endif %}
</h5> </h5>
<p class="card-text"> <p class="card-text">
{% trans "Absent" %}: {{ person.person.absences_count }} {% trans "Absent" %}: {{ person.person.absences_count }}
......
{% load data_helpers time_helpers i18n %} {% load data_helpers time_helpers i18n rules %}
{% if not persons %} {% if not persons %}
<div class="alert primary"> <div class="alert primary">
...@@ -107,6 +107,14 @@ ...@@ -107,6 +107,14 @@
<span class="hide-on-med-and-down"> {% trans "Show more details" %}</span> <span class="hide-on-med-and-down"> {% trans "Show more details" %}</span>
<span class="hide-on-large-only">{% trans "Details" %}</span> <span class="hide-on-large-only">{% trans "Details" %}</span>
</a> </a>
{% has_perm "alsijil.register_absence" user person as can_register_absence %}
{% if can_register_absence %}
<a class="btn primary-color waves-effect waves-light" href="{% url "register_absence" person.pk %}">
<i class="material-icons left">rate_review</i>
{% trans "Register absence" %}
</a>
{% endif %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
......
...@@ -36,7 +36,7 @@ urlpatterns = [ ...@@ -36,7 +36,7 @@ urlpatterns = [
views.DeletePersonalNoteView.as_view(), views.DeletePersonalNoteView.as_view(),
name="delete_personal_note", name="delete_personal_note",
), ),
path("absence/new", views.register_absence, name="register_absence"), path("absence/new/<int:id_>/", views.register_absence, name="register_absence"),
path("extra_marks/", views.ExtraMarkListView.as_view(), name="extra_marks"), path("extra_marks/", views.ExtraMarkListView.as_view(), name="extra_marks"),
path( path(
"extra_marks/create/", "extra_marks/create/",
......
...@@ -680,49 +680,47 @@ def overview_person(request: HttpRequest, id_: Optional[int] = None) -> HttpResp ...@@ -680,49 +680,47 @@ def overview_person(request: HttpRequest, id_: Optional[int] = None) -> HttpResp
return render(request, "alsijil/class_register/person.html", context) return render(request, "alsijil/class_register/person.html", context)
@permission_required("alsijil.view_register_absence") @permission_required("alsijil.register_absence", fn=objectgetter_optional(Person))
def register_absence(request: HttpRequest) -> HttpResponse: def register_absence(request: HttpRequest, id_: int) -> HttpResponse:
context = {} context = {}
person = get_object_or_404(Person, pk=id_)
register_absence_form = RegisterAbsenceForm(request.POST or None) register_absence_form = RegisterAbsenceForm(request.POST or None)
if request.method == "POST": if request.method == "POST" and register_absence_form.is_valid():
if register_absence_form.is_valid() and request.user.has_perm( # Get data from form
"alsijil.register_absence", register_absence_form.cleaned_data["person"] # person = register_absence_form.cleaned_data["person"]
): start_date = register_absence_form.cleaned_data["date_start"]
# Get data from form end_date = register_absence_form.cleaned_data["date_end"]
person = register_absence_form.cleaned_data["person"] from_period = register_absence_form.cleaned_data["from_period"]
start_date = register_absence_form.cleaned_data["date_start"] to_period = register_absence_form.cleaned_data["to_period"]
end_date = register_absence_form.cleaned_data["date_end"] absent = register_absence_form.cleaned_data["absent"]
from_period = register_absence_form.cleaned_data["from_period"] excused = register_absence_form.cleaned_data["excused"]
to_period = register_absence_form.cleaned_data["to_period"] excuse_type = register_absence_form.cleaned_data["excuse_type"]
absent = register_absence_form.cleaned_data["absent"] remarks = register_absence_form.cleaned_data["remarks"]
excused = register_absence_form.cleaned_data["excused"]
excuse_type = register_absence_form.cleaned_data["excuse_type"] # Mark person as absent
remarks = register_absence_form.cleaned_data["remarks"] delta = end_date - start_date
for i in range(delta.days + 1):
# Mark person as absent from_period_on_day = from_period if i == 0 else TimePeriod.period_min
delta = end_date - start_date to_period_on_day = to_period if i == delta.days else TimePeriod.period_max
for i in range(delta.days + 1): day = start_date + timedelta(days=i)
from_period_on_day = from_period if i == 0 else TimePeriod.period_min
to_period_on_day = ( person.mark_absent(
to_period if i == delta.days else TimePeriod.period_max day,
) from_period_on_day,
day = start_date + timedelta(days=i) absent,
excused,
person.mark_absent( excuse_type,
day, remarks,
from_period_on_day, to_period_on_day,
absent, )
excused,
excuse_type,
remarks,
to_period_on_day,
)
messages.success(request, _("The absence has been saved.")) messages.success(request, _("The absence has been saved."))
return redirect("register_absence") return redirect("overview_person", person.pk)
context["person"] = person
context["register_absence_form"] = register_absence_form context["register_absence_form"] = register_absence_form
return render(request, "alsijil/absences/register.html", context) return render(request, "alsijil/absences/register.html", context)
......
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