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
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load material_form i18n %}
{% block browser_title %}{% blocktrans %}Edit extra mark{% endblocktrans %}{% endblock %}
{% block page_title %}{% blocktrans %}Edit extra mark{% endblocktrans %}{% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
{% form form=form %}{% endform %}
{% include "core/partials/save_button.html" %}
</form>
{% endblock %}
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load i18n %}
{% load render_table from django_tables2 %}
{% block browser_title %}{% blocktrans %}Extra marks{% endblocktrans %}{% endblock %}
{% block page_title %}{% blocktrans %}Extra marks{% endblocktrans %}{% endblock %}
{% block content %}
<a class="btn green waves-effect waves-light" href="{% url 'create_extra_mark' %}">
<i class="material-icons left">add</i>
{% trans "Create extra mark" %}
</a>
{% render_table table %}
{% endblock %}
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load i18n %}
{% load render_table from django_tables2 %}
{% block browser_title %}{% blocktrans %}All personal note filters{% endblocktrans %}{% endblock %}
{% block page_title %}{% blocktrans %}Personal note filters{% endblocktrans %}{% endblock %}
{% block content %}
<a href="{% url 'create_personal_note_filter' %}" class="waves-effect waves-light green btn">
<i class="material-icons left">add</i>{% blocktrans %}Add filter{% endblocktrans %}
</a>
{% render_table personal_note_filters_table %}
{% endblock %}
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load material_form i18n static %}
{% block browser_title %}
{% if personal_note_filter %}
{% trans "Update personal note filter" %}
{% else %}
{% trans "Create personal note filter" %}
{% endif %}
{% endblock %}
{% block page_title %}
{% if personal_note_filter %}
{% trans "Update personal note filter" %}
{% else %}
{% trans "Create personal note filter" %}
{% endif %}
{% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
{% form form=personal_note_filter_form %}{% endform %}
{% include "core/partials/save_button.html" %}
{% if personal_note_filter %}
<a href="{% url 'delete_personal_note_filter' personal_note_filter.id %}"
class="waves-effect waves-light btn red">
<i class="material-icons left">delete</i>{% blocktrans %}Delete filter{% endblocktrans %}
</a>
{% endif %}
</form>
{% endblock %}
......@@ -97,6 +97,18 @@
</ul>
{% endif %}
{% if extra_marks %}
<h5>{% trans "Available extra marks" %}</h5>
<ul class="collection">
{% for extra_mark in extra_marks %}
<li class="collection-item">
<strong>{{ extra_mark.short_name }}</strong> {{ extra_mark.name }}
</li>
{% endfor %}
</ul>
{% endif %}
<div class="page-break">&nbsp;</div>
......@@ -117,6 +129,9 @@
{% endfor %}
<th>{% trans '(u)' %}</th>
<th>{% trans '(b)' %}</th>
{% for extra_mark in extra_marks %}
<th>{{ extra_mark.short_name }}</th>
{% endfor %}
</tr>
</thead>
......@@ -135,6 +150,9 @@
{% endfor %}
<td>{{ person.unexcused }}</td>
<td>{{ person.tardiness }}'</td>
{% for extra_mark in extra_marks %}
<td>{{ person|get_dict:extra_mark.count_label }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
......@@ -245,29 +263,6 @@
</tr>
</table>
{% if personal_note_filters %}
<h5>{% trans 'Statistics on remarks' %}</h5>
<table>
<thead>
<tr>
<th>{% trans 'Description' %}</th>
<th>{% trans 'Count' %}</th>
</tr>
</thead>
<tbody>
{% for note_filter in personal_note_filters %}
<tr>
<td>{{ note_filter.description }}</td>
{% with "_personal_notes_with_"|add:note_filter.identifier as identifier %}
<td>{{ person|get_dict:identifier }}</td>
{% endwith %}
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
<h5>{% trans 'Absences and tardiness' %}</h5>
<table>
<tr>
......@@ -294,6 +289,18 @@
</tr>
</table>
{% if extra_marks %}
<h5>{% trans 'Extra marks' %}</h5>
<table>
{% for extra_mark in extra_marks %}
<tr>
<th>{{ extra_mark.name }}</th>
<td>{{ person|get_dict:extra_mark.count_label }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
<h5>{% trans 'Relevant personal notes' %}</h5>
<table class="small-print">
<thead>
......@@ -304,38 +311,45 @@
<th>{% trans 'Te.' %}</th>
<th>{% trans 'Absent' %}</th>
<th>{% trans 'Tard.' %}</th>
<th>{% trans 'Remarks' %}</th>
<th colspan="2">{% trans 'Remarks' %}</th>
</tr>
</thead>
<tbody>
{% for note in person.personal_notes.all %}
{% if note.absent or note.late or note.remarks %}
{% period_to_date note.week note.lesson_period.period as note_date %}
<tr>
<td>{{ note_date }}</td>
<td>{{ note.lesson_period.period.period }}</td>
<td>{{ note.lesson_period.get_subject.short_name }} </td>
<td>{{ note.lesson_period.get_teachers.first.short_name }}</td>
<td>
{% if note.absent %}
{% trans 'Yes' %}
{% if note.excused %}
{% if note.excuse_type %}
({{ note.excuse_type.short_name }})
{% else %}
({% trans 'e' %})
{% if note.lesson_period in lesson_periods %}
{% if note.absent or note.late or note.remarks or note.extra_marks.all %}
{% period_to_date note.week note.lesson_period.period as note_date %}
<tr>
<td>{{ note_date }}</td>
<td>{{ note.lesson_period.period.period }}</td>
<td>{{ note.lesson_period.get_subject.short_name }} </td>
<td>{{ note.lesson_period.get_teachers.first.short_name }}</td>
<td>
{% if note.absent %}
{% trans 'Yes' %}
{% if note.excused %}
{% if note.excuse_type %}
({{ note.excuse_type.short_name }})
{% else %}
({% trans 'e' %})
{% endif %}
{% endif %}
{% endif %}
{% endif %}
</td>
<td>
{% if note.late %}
{{ note.late }}'
{% endif %}
</td>
<td>{{ note.remarks }}</td>
</tr>
</td>
<td>
{% if note.late %}
{{ note.late }}'
{% endif %}
</td>
<td>
{% for extra_mark in note.extra_marks.all %}
{{ extra_mark.short_name }}{% if not forloop.last %},{% endif %}
{% endfor %}
</td>
<td>{{ note.remarks }}</td>
</tr>
{% endif %}
{% endif %}
{% endfor %}
</tbody>
......@@ -396,36 +410,45 @@
</td>
<td class="lesson-homework">{{ documentations.0.homework }}</td>
<td class="lesson-notes">
{{ documentations.0.group_note }}
{% for note in notes %}
{% if note.absent %}
<span class="lesson-note-absent">
{{ note.person.last_name }}, {{ note.person.first_name|slice:"0:1" }}.
{% if note.excused %}
<span class="lesson-note-excused">
{% if note.excuse_type %}
({{ note.excuse_type.short_name }})
{% else %}
({% trans 'e' %})
{% endif %}
</span>
{% endif %}
{% if group in note.groups_of_person.all %}
{% if note.absent %}
<span class="lesson-note-absent">
{{ note.person.last_name }}, {{ note.person.first_name|slice:"0:1" }}.
{% if note.excused %}
<span class="lesson-note-excused">
{% if note.excuse_type %}
({{ note.excuse_type.short_name }})
{% else %}
({% trans 'e' %})
{% endif %}
</span>
{% endif %}
</span>
{% endif %}
{% if note.late %}
<span class="lesson-note-late">
{{ note.person.last_name }}, {{ note.person.first_name|slice:"0:1" }}.
({{ note.late }}′)
{% if note.excused %}
<span class="lesson-note-excused">
{% if note.excuse_type %}
({{ note.excuse_type.short_name }})
{% else %}
({% trans 'e' %})
{% endif %}
</span>
{% endif %}
{% endif %}
{% if note.late %}
<span class="lesson-note-late">
{{ note.person.last_name }}, {{ note.person.first_name|slice:"0:1" }}.
({{ note.late }}′)
{% if note.excused %}
<span class="lesson-note-excused">
{% if note.excuse_type %}
({{ note.excuse_type.short_name }})
{% else %}
({% trans 'e' %})
{% endif %}
</span>
{% endif %}
</span>
{% endif %}
{% endif %}
{% for extra_mark in note.extra_marks.all %}
<span>
{{ note.person.last_name }}, {{ note.person.first_name|slice:"0:1" }}.
({{ extra_mark.short_name }})
</span>
{% endfor %}
{% endfor %}
</td>
<td class="lesson-te">
......
......@@ -21,25 +21,21 @@ urlpatterns = [
"print/group/<int:id_>", views.full_register_group, name="full_register_group"
),
path("absence/new", views.register_absence, name="register_absence"),
path("extra_marks/", views.ExtraMarkListView.as_view(), name="extra_marks"),
path(
"filters/list",
views.list_personal_note_filters,
name="list_personal_note_filters",
"extra_marks/create/",
views.ExtraMarkCreateView.as_view(),
name="create_extra_mark",
),
path(
"filters/create",
views.edit_personal_note_filter,
name="create_personal_note_filter",
"extra_marks/<int:pk>/edit/",
views.ExtraMarkEditView.as_view(),
name="edit_extra_mark",
),
path(
"filters/edit/<int:id_>",
views.edit_personal_note_filter,
name="edit_personal_note_filter",
),
path(
"filters/delete/<int:id_>",
views.delete_personal_note_filter,
name="delete_personal_note_filter",
"extra_marks/<int:pk>/delete/",
views.ExtraMarkDeleteView.as_view(),
name="delete_extra_mark",
),
path("excuse_types/", views.ExcuseTypeListView.as_view(), name="excuse_types"),
path(
......
......@@ -16,20 +16,21 @@ from rules.contrib.views import PermissionRequiredMixin
from aleksis.apps.chronos.managers import TimetableType
from aleksis.apps.chronos.models import LessonPeriod
from aleksis.apps.chronos.util.chronos_helpers import get_el_by_pk
from aleksis.apps.chronos.util.date import week_weekday_to_date
from aleksis.core.mixins import AdvancedCreateView, AdvancedDeleteView, AdvancedEditView
from aleksis.core.models import Group, Person, SchoolTerm
from aleksis.core.util import messages
from .forms import (
ExcuseTypeForm,
ExtraMarkForm,
LessonDocumentationForm,
PersonalNoteFilterForm,
PersonalNoteFormSet,
RegisterAbsenceForm,
SelectForm,
)
from .models import ExcuseType, LessonDocumentation, PersonalNoteFilter
from .tables import ExcuseTypeTable, PersonalNoteFilterTable
from .models import ExcuseType, ExtraMark, LessonDocumentation
from .tables import ExcuseTypeTable, ExtraMarkTable
def lesson(
......@@ -46,6 +47,14 @@ def lesson(
lesson_period = LessonPeriod.objects.annotate_week(wanted_week).get(
pk=period_id
)
date_of_lesson = week_weekday_to_date(wanted_week, lesson_period.period.weekday)
if (
date_of_lesson < lesson_period.lesson.validity.date_start
or date_of_lesson > lesson_period.lesson.validity.date_end
):
return HttpResponseNotFound()
else:
# Determine current lesson by current date and time
lesson_period = (
......@@ -246,6 +255,21 @@ def week_view(
)
)
for extra_mark in ExtraMark.objects.all():
persons_qs = persons_qs.annotate(
**{
extra_mark.count_label: Count(
"personal_notes",
filter=Q(
personal_notes__lesson_period__in=lesson_periods_pk,
personal_notes__week=wanted_week.week,
personal_notes__extra_marks=extra_mark,
),
distinct=True,
)
}
)
persons = []
for person in persons_qs:
persons.append(
......@@ -264,6 +288,7 @@ def week_view(
lesson_periods, key=lambda x: (x.period.weekday, x.period.period)
)
context["extra_marks"] = ExtraMark.objects.all()
context["week"] = wanted_week
context["lesson_periods"] = lesson_periods
context["persons"] = persons
......@@ -290,18 +315,19 @@ def full_register_group(request: HttpRequest, id_: int) -> HttpResponse:
group = get_object_or_404(Group, pk=id_)
current_school_term = SchoolTerm.current
if not current_school_term:
return HttpResponseNotFound(_("There is no current school term."))
# Get all lesson periods for the selected group
lesson_periods = (
LessonPeriod.objects.filter_group(group)
.filter(lesson__validity__school_term=current_school_term)
.distinct()
.prefetch_related("documentations", "personal_notes")
)
current_school_term = SchoolTerm.current
if not current_school_term:
return HttpResponseNotFound(_("There is no current school term."))
weeks = CalendarWeek.weeks_within(
current_school_term.date_start, current_school_term.date_end,
)
......@@ -334,9 +360,16 @@ def full_register_group(request: HttpRequest, id_: int) -> HttpResponse:
(lesson_period, documentations, notes, substitution)
)
persons = group.members.annotate(
persons = Person.objects.filter(
personal_notes__groups_of_person=group,
personal_notes__lesson_period__lesson__validity__school_term=current_school_term,
).annotate(
absences_count=Count(
"personal_notes__absent", filter=Q(personal_notes__absent=True)
"personal_notes__absent",
filter=Q(
personal_notes__absent=True,
personal_notes__lesson_period__lesson__validity__school_term=current_school_term,
),
),
excused=Count(
"personal_notes__absent",
......@@ -344,38 +377,38 @@ def full_register_group(request: HttpRequest, id_: int) -> HttpResponse:
personal_notes__absent=True,
personal_notes__excused=True,
personal_notes__excuse_type__isnull=True,
personal_notes__lesson_period__lesson__validity__school_term=current_school_term,
),
),
unexcused=Count(
"personal_notes__absent",
filter=Q(personal_notes__absent=True, personal_notes__excused=False),
filter=Q(
personal_notes__absent=True,
personal_notes__excused=False,
personal_notes__lesson_period__lesson__validity__school_term=current_school_term,
),
),
tardiness=Sum("personal_notes__late"),
)
for excuse_type in ExcuseType.objects.all():
for extra_mark in ExtraMark.objects.all():
persons = persons.annotate(
**{
excuse_type.count_label: Count(
"personal_notes__absent",
filter=Q(
personal_notes__absent=True,
personal_notes__excuse_type=excuse_type,
),
extra_mark.count_label: Count(
"personal_notes", filter=Q(personal_notes__extra_marks=extra_mark,personal_notes__lesson_period__lesson__validity__school_term=current_school_term),
)
}
)
# FIXME Move to manager
personal_note_filters = PersonalNoteFilter.objects.all()
for personal_note_filter in personal_note_filters:
for excuse_type in ExcuseType.objects.all():
persons = persons.annotate(
**{
"_personal_notes_with_%s"
% personal_note_filter.identifier: Count(
"personal_notes__remarks",
excuse_type.count_label: Count(
"personal_notes__absent",
filter=Q(
personal_notes__remarks__iregex=personal_note_filter.regex
personal_notes__absent=True,
personal_notes__excuse_type=excuse_type,
personal_notes__lesson_period__lesson__validity__school_term=current_school_term,
),
)
}
......@@ -383,11 +416,12 @@ def full_register_group(request: HttpRequest, id_: int) -> HttpResponse:
context["school_term"] = current_school_term
context["persons"] = persons
context["personal_note_filters"] = personal_note_filters
context["excuse_types"] = ExcuseType.objects.all()
context["extra_marks"] = ExtraMark.objects.all()
context["group"] = group
context["weeks"] = weeks
context["periods_by_day"] = periods_by_day
context["lesson_periods"] = lesson_periods
context["today"] = date.today()
return render(request, "alsijil/print/full_register.html", context)
......@@ -424,57 +458,45 @@ def register_absence(request: HttpRequest) -> HttpResponse:
return render(request, "alsijil/absences/register.html", context)
def list_personal_note_filters(request: HttpRequest) -> HttpResponse:
context = {}
personal_note_filters = PersonalNoteFilter.objects.all()
# Prepare table
personal_note_filters_table = PersonalNoteFilterTable(personal_note_filters)
RequestConfig(request).configure(personal_note_filters_table)
class ExtraMarkListView(SingleTableView, PermissionRequiredMixin):
"""Table of all extra marks."""
context["personal_note_filters_table"] = personal_note_filters_table
model = ExtraMark
table_class = ExtraMarkTable
permission_required = "core.view_extramark"
template_name = "alsijil/extra_mark/list.html"
return render(request, "alsijil/personal_note_filter/list.html", context)
class ExtraMarkCreateView(AdvancedCreateView, PermissionRequiredMixin):
"""Create view for extra marks."""
def edit_personal_note_filter(
request: HttpRequest, id_: Optional["int"] = None
) -> HttpResponse:
context = {}
model = ExtraMark
form_class = ExtraMarkForm
permission_required = "core.create_extramark"
template_name = "alsijil/extra_mark/create.html"
success_url = reverse_lazy("extra_marks")
success_message = _("The extra mark has been created.")
if id_:
personal_note_filter = PersonalNoteFilter.objects.get(id=id_)
context["personal_note_filter"] = personal_note_filter
personal_note_filter_form = PersonalNoteFilterForm(
request.POST or None, instance=personal_note_filter
)
else:
personal_note_filter_form = PersonalNoteFilterForm(request.POST or None)
if request.method == "POST":
if personal_note_filter_form.is_valid():
personal_note_filter_form.save(commit=True)
messages.success(request, _("The filter has been saved"))
return redirect("list_personal_note_filters")
class ExtraMarkEditView(AdvancedEditView, PermissionRequiredMixin):
"""Edit view for extra marks."""
context["personal_note_filter_form"] = personal_note_filter_form
model = ExtraMark
form_class = ExtraMarkForm
permission_required = "core.edit_extramark"
template_name = "alsijil/extra_mark/edit.html"
success_url = reverse_lazy("extra_marks")
success_message = _("The extra mark has been saved.")
return render(request, "alsijil/personal_note_filter/manage.html", context)
class ExtraMarkDeleteView(AdvancedDeleteView, PermissionRequiredMixin, RevisionMixin):
"""Delete view for extra marks"""
def delete_personal_note_filter(request: HttpRequest, id_: int) -> HttpResponse:
context = {}
personal_note_filter = get_object_or_404(PersonalNoteFilter, pk=id_)
PersonalNoteFilter.objects.filter(pk=id_).delete()
messages.success(request, _("The filter has been deleted."))
context["personal_note_filter"] = personal_note_filter
return redirect("list_personal_note_filters")
model = ExtraMark
permission_required = "core.delete_extramark"
template_name = "core/pages/delete.html"
success_url = reverse_lazy("extra_marks")
success_message = _("The extra mark has been deleted.")
class ExcuseTypeListView(SingleTableView, PermissionRequiredMixin):
......