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 (5)
......@@ -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")
......
......@@ -21,6 +21,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.
......@@ -40,6 +41,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(
......@@ -104,7 +108,10 @@ def get_personal_notes(self, persons: QuerySet, wanted_week: CalendarWeek):
personal_note.groups_of_person.set(personal_note.person.member_of.all())
return PersonalNote.objects.select_related("person").filter(
lesson_period=self, week=wanted_week.week, year=wanted_week.year
lesson_period=self,
week=wanted_week.week,
year=wanted_week.year,
person__in=persons,
)
......
......@@ -10,17 +10,17 @@ from aleksis.core.util.predicates import (
from .util.predicates import (
has_any_object_absence,
has_lesson_group_object_perm,
has_personal_note_group_perm,
has_person_group_object_perm,
has_personal_note_group_perm,
is_group_member,
is_group_owner,
is_lesson_parent_group_owner,
is_lesson_participant,
is_lesson_teacher,
is_own_personal_note,
is_person_group_owner,
is_personal_note_lesson_parent_group_owner,
is_personal_note_lesson_teacher,
is_person_group_owner,
)
# View lesson
......@@ -36,6 +36,15 @@ add_perm("alsijil.view_lesson", view_lesson_predicate)
# View lesson in menu
add_perm("alsijil.view_lesson_menu", has_person)
# View lesson personal notes
view_lesson_personal_notes_predicate = has_person & (
has_global_perm("alsijil.view_personalnote")
| has_lesson_group_object_perm("core.view_personalnote_group")
| is_lesson_teacher
| is_lesson_parent_group_owner
)
add_perm("alsijil.view_lesson_personalnote", view_lesson_personal_notes_predicate)
# View personal note
view_personal_note_predicate = has_person & (
has_global_perm("alsijil.view_personalnote")
......@@ -95,8 +104,7 @@ 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
has_global_perm("alsijil.register_absence") | has_any_object_absence
)
add_perm("alsijil.view_register_absence", view_register_absence_predicate)
......
......@@ -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 %}
......@@ -7,8 +7,8 @@ from rules import predicate
from aleksis.apps.chronos.models import LessonPeriod
from aleksis.core.models import Group, Person
from aleksis.core.util.predicates import check_object_permission
from aleksis.core.util.core_helpers import get_site_preferences
from aleksis.core.util.predicates import check_object_permission
from ..models import PersonalNote
......@@ -21,10 +21,10 @@ def is_lesson_teacher(user: User, obj: LessonPeriod) -> bool:
in the lesson or the substitution linked to the given LessonPeriod.
"""
if obj:
return (
user.person in obj.lesson.teachers.all()
or user.person in Person.objects.filter(lesson_substitutions=obj.get_substitution())
)
sub = obj.get_substitution()
if sub and sub in user.person.lesson_substitutions.all():
return True
return user.person in obj.lesson.teachers.all()
return True
......@@ -154,7 +154,10 @@ def is_own_personal_note(user: User, obj: PersonalNote) -> bool:
Is configurable via dynamic preferences.
"""
if hasattr(obj, "person"):
if get_site_preferences()["alsijil__view_own_personal_notes"] and obj.person is user.person:
if (
get_site_preferences()["alsijil__view_own_personal_notes"]
and obj.person is user.person
):
return True
return False
......@@ -168,9 +171,8 @@ def is_personal_note_lesson_teacher(user: User, obj: PersonalNote) -> bool:
"""
if hasattr(obj, "lesson_period"):
if hasattr(obj.lesson_period, "lesson"):
return (
user.person in obj.lesson_period.lesson.teachers.all()
or user.person in Person.objects.filter(lesson_substitutions=obj.lesson_period.get_substitution())
return user.person in obj.lesson_period.lesson.teachers.all() or user.person in Person.objects.filter(
lesson_substitutions=obj.lesson_period.get_substitution()
)
return False
return False
......@@ -186,7 +188,9 @@ def is_personal_note_lesson_parent_group_owner(user: User, obj: PersonalNote) ->
"""
if hasattr(obj, "lesson_period"):
if hasattr(obj.lesson_period, "lesson"):
return obj.lesson_period.lesson.groups.filter(parent_groups__owners=user.person).exists()
return obj.lesson_period.lesson.groups.filter(
parent_groups__owners=user.person
).exists()
return False
return False
......@@ -200,5 +204,7 @@ def has_any_object_absence(user: User) -> bool:
return True
if Person.objects.filter(member_of__owners=user.person).exists():
return True
if Person.objects.filter(member_of__in=get_objects_for_user(user, "core.register_absence_group", Group)).exists():
if Person.objects.filter(
member_of__in=get_objects_for_user(user, "core.register_absence_group", Group)
).exists():
return True
......@@ -14,7 +14,7 @@ from reversion.views import RevisionMixin
from rules.contrib.views import PermissionRequiredMixin, permission_required
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
......@@ -107,9 +107,9 @@ def lesson(
)
# Create a formset that holds all personal notes for all persons in this lesson
persons = Person.objects
persons = Person.objects.all()
if not request.user.has_perm("alsijil.view_lesson_personalnote", lesson_period):
persons = persons.filter(pk=request.user.pk)
persons = persons.filter(pk=request.user.person.pk)
persons_qs = lesson_period.get_personal_notes(persons, wanted_week)
personal_note_formset = PersonalNoteFormSet(
request.POST or None, queryset=persons_qs, prefix="personal_notes"
......@@ -485,19 +485,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
......