Skip to content
Snippets Groups Projects
Verified Commit 2b83a633 authored by Nik | Klampfradler's avatar Nik | Klampfradler
Browse files

[Reformat} Run isort and black

parent 874b76b4
No related branches found
No related tags found
No related merge requests found
import pkg_resources
try:
__version__ = pkg_resources.get_distribution('BiscuIT-App-Alsijil').version
__version__ = pkg_resources.get_distribution("BiscuIT-App-Alsijil").version
except Exception:
__version__ = 'unknown'
__version__ = "unknown"
default_app_config = 'biscuit.apps.alsijil.apps.AlsijilConfig'
default_app_config = "biscuit.apps.alsijil.apps.AlsijilConfig"
......@@ -2,5 +2,5 @@ from biscuit.core.util.apps import AppConfig
class AlsijilConfig(AppConfig):
name = 'biscuit.apps.alsijil'
verbose_name = 'BiscuIT - Alsijil (Class register)'
name = "biscuit.apps.alsijil"
verbose_name = "BiscuIT - Alsijil (Class register)"
from datetime import datetime
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
......@@ -13,54 +15,75 @@ from .models import LessonDocumentation, PersonalNote, PersonalNoteFilter
class LessonDocumentationForm(forms.ModelForm):
class Meta:
model = LessonDocumentation
fields = ['topic', 'homework']
fields = ["topic", "homework"]
class PersonalNoteForm(forms.ModelForm):
class Meta:
model = PersonalNote
fields = ['absent', 'late', 'excused', 'remarks']
fields = ["absent", "late", "excused", "remarks"]
person_name = forms.CharField(disabled=True)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['person_name'].widget.attrs.update(
{'class': 'alsijil-lesson-personal-note-name'})
self.fields["person_name"].widget.attrs.update(
{"class": "alsijil-lesson-personal-note-name"}
)
if self.instance and getattr(self.instance, 'person', None):
self.fields['person_name'].initial = str(self.instance.person)
if self.instance and getattr(self.instance, "person", None):
self.fields["person_name"].initial = str(self.instance.person)
class SelectForm(forms.Form):
group = forms.ModelChoiceField(
queryset=Group.objects.annotate(lessons_count=Count('lessons')).filter(lessons_count__gt=0),
label=_('Group'), required=False, widget=Select2Widget)
queryset=Group.objects.annotate(lessons_count=Count("lessons")).filter(
lessons_count__gt=0
),
label=_("Group"),
required=False,
widget=Select2Widget,
)
teacher = forms.ModelChoiceField(
queryset=Person.objects.annotate(lessons_count=Count(
'lessons_as_teacher')).filter(lessons_count__gt=0),
label=_('Teacher'), required=False, widget=Select2Widget)
queryset=Person.objects.annotate(
lessons_count=Count("lessons_as_teacher")
).filter(lessons_count__gt=0),
label=_("Teacher"),
required=False,
widget=Select2Widget,
)
room = forms.ModelChoiceField(
queryset=Room.objects.annotate(lessons_count=Count(
'lesson_periods')).filter(lessons_count__gt=0),
label=_('Room'), required=False, widget=Select2Widget)
queryset=Room.objects.annotate(lessons_count=Count("lesson_periods")).filter(
lessons_count__gt=0
),
label=_("Room"),
required=False,
widget=Select2Widget,
)
PersonalNoteFormSet = forms.modelformset_factory(
PersonalNote, form=PersonalNoteForm, max_num=0, extra=0)
PersonalNote, form=PersonalNoteForm, max_num=0, extra=0
)
class RegisterAbsenceForm(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)
from_period = forms.IntegerField(label=_('From period'), initial=0, min_value=0)
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)
remarks = forms.CharField(label=_('Remarks'), max_length=30, required=False)
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
)
from_period = forms.IntegerField(label=_("From period"), initial=0, min_value=0)
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)
remarks = forms.CharField(label=_("Remarks"), max_length=30, required=False)
class PersonalNoteFilterForm(forms.ModelForm):
class Meta:
model = PersonalNoteFilter
fields = ['identifier', 'description', 'regex']
fields = ["identifier", "description", "regex"]
from django.utils.translation import ugettext_lazy as _
MENUS = {
'NAV_MENU_CORE': [
"NAV_MENU_CORE": [
{
'name': _('Class register'),
'url': '#',
'root': True,
'validators': ['menu_generator.validators.is_authenticated', 'biscuit.core.util.core_helpers.has_person'],
'submenu': [
"name": _("Class register"),
"url": "#",
"root": True,
"validators": [
"menu_generator.validators.is_authenticated",
"biscuit.core.util.core_helpers.has_person",
],
"submenu": [
{
'name': _('Current lesson'),
'url': 'lesson',
'validators': ['menu_generator.validators.is_authenticated']
"name": _("Current lesson"),
"url": "lesson",
"validators": ["menu_generator.validators.is_authenticated"],
},
{
'name': _('Current week'),
'url': 'week_view',
'validators': ['menu_generator.validators.is_authenticated']
"name": _("Current week"),
"url": "week_view",
"validators": ["menu_generator.validators.is_authenticated"],
},
{
'name': _('Register absence'),
'url': 'register_absence',
'validators': ['menu_generator.validators.is_superuser']
"name": _("Register absence"),
"url": "register_absence",
"validators": ["menu_generator.validators.is_superuser"],
},
{
'name': _('Personal note filters'),
'url': 'list_personal_note_filters',
'validators': ['menu_generator.validators.is_superuser']
}
]
"name": _("Personal note filters"),
"url": "list_personal_note_filters",
"validators": ["menu_generator.validators.is_superuser"],
},
],
}
]
}
# Generated by Django 2.2.5 on 2019-09-03 18:30
import biscuit.core.util.core_helpers
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
import biscuit.core.util.core_helpers
class Migration(migrations.Migration):
......@@ -10,42 +11,114 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('chronos', '0001_initial'),
('core', '0001_initial'),
("chronos", "0001_initial"),
("core", "0001_initial"),
]
operations = [
migrations.CreateModel(
name='PersonalNote',
name="PersonalNote",
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('week', models.IntegerField()),
('absent', models.BooleanField(default=False)),
('late', models.IntegerField(default=0)),
('excused', models.BooleanField(default=False)),
('remarks', models.CharField(blank=True, max_length=200)),
('lesson_period', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='chronos.LessonPeriod')),
('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='personal_notes', to='core.Person')),
('school', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='core.School')),
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("week", models.IntegerField()),
("absent", models.BooleanField(default=False)),
("late", models.IntegerField(default=0)),
("excused", models.BooleanField(default=False)),
("remarks", models.CharField(blank=True, max_length=200)),
(
"lesson_period",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="chronos.LessonPeriod",
),
),
(
"person",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="personal_notes",
to="core.Person",
),
),
(
"school",
models.ForeignKey(
default=1,
on_delete=django.db.models.deletion.CASCADE,
to="core.School",
),
),
],
options={
'ordering': ['lesson_period__lesson__date_start', 'week', 'lesson_period__period__weekday', 'lesson_period__period__period', 'person__last_name', 'person__first_name'],
'unique_together': {('school', 'lesson_period', 'week', 'person')},
"ordering": [
"lesson_period__lesson__date_start",
"week",
"lesson_period__period__weekday",
"lesson_period__period__period",
"person__last_name",
"person__first_name",
],
"unique_together": {("school", "lesson_period", "week", "person")},
},
),
migrations.CreateModel(
name='LessonDocumentation',
name="LessonDocumentation",
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('week', models.IntegerField()),
('topic', models.CharField(blank=True, max_length=200, verbose_name='Lesson topic')),
('homework', models.CharField(blank=True, max_length=200, verbose_name='Homework')),
('lesson_period', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documentations', to='chronos.LessonPeriod')),
('school', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='core.School')),
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("week", models.IntegerField()),
(
"topic",
models.CharField(
blank=True, max_length=200, verbose_name="Lesson topic"
),
),
(
"homework",
models.CharField(
blank=True, max_length=200, verbose_name="Homework"
),
),
(
"lesson_period",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="documentations",
to="chronos.LessonPeriod",
),
),
(
"school",
models.ForeignKey(
default=1,
on_delete=django.db.models.deletion.CASCADE,
to="core.School",
),
),
],
options={
'ordering': ['lesson_period__lesson__date_start', 'week', 'lesson_period__period__weekday', 'lesson_period__period__period'],
'unique_together': {('school', 'lesson_period', 'week')},
"ordering": [
"lesson_period__lesson__date_start",
"week",
"lesson_period__period__weekday",
"lesson_period__period__period",
],
"unique_together": {("school", "lesson_period", "week")},
},
),
]
# Generated by Django 2.2.5 on 2019-11-20 14:21
import django.db.models.deletion
from django.db import migrations, models
import biscuit.apps.alsijil.models
import biscuit.core.util.core_helpers
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('core', '0003_school_logo'),
('alsijil', '0001_initial'),
("core", "0003_school_logo"),
("alsijil", "0001_initial"),
]
operations = [
migrations.CreateModel(
name='PersonalNoteFilter',
name="PersonalNoteFilter",
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('identifier', models.CharField(max_length=30, validators=[biscuit.apps.alsijil.models.isidentifier], verbose_name='Identifier')),
('description', models.CharField(blank=True, max_length=60, verbose_name='Description')),
('regex', models.CharField(max_length=100, verbose_name='Match expression')),
('school', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='core.School')),
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"identifier",
models.CharField(
max_length=30,
validators=[biscuit.apps.alsijil.models.isidentifier],
verbose_name="Identifier",
),
),
(
"description",
models.CharField(
blank=True, max_length=60, verbose_name="Description"
),
),
(
"regex",
models.CharField(max_length=100, verbose_name="Match expression"),
),
(
"school",
models.ForeignKey(
default=1,
on_delete=django.db.models.deletion.CASCADE,
to="core.School",
),
),
],
options={
'ordering': ['identifier'],
'unique_together': {('school', 'regex'), ('school', 'description'), ('school', 'identifier')},
"ordering": ["identifier"],
"unique_together": {
("school", "regex"),
("school", "description"),
("school", "identifier"),
},
},
),
]
......@@ -10,7 +10,14 @@ from .models import PersonalNote
@Person.method
def mark_absent(self, day: date, from_period: int = 0, absent: bool = True, excused: bool = False, remarks: str = ''):
def mark_absent(
self,
day: date,
from_period: int = 0,
absent: bool = True,
excused: bool = False,
remarks: str = "",
):
""" Mark a person absent for all lessons in a day, optionally starting with
a selected period number.
......@@ -27,9 +34,7 @@ def mark_absent(self, day: date, from_period: int = 0, absent: bool = True, excu
wanted_week = CalendarWeek.from_date(day)
# Get all lessons of this person on the specified day
lesson_periods = self.lesson_periods_as_participant.on_day(
day
).filter(
lesson_periods = self.lesson_periods_as_participant.on_day(day).filter(
period__period__gte=from_period
)
......@@ -39,15 +44,12 @@ def mark_absent(self, day: date, from_period: int = 0, absent: bool = True, excu
person=self,
lesson_period=lesson_period,
week=wanted_week.week,
defaults={
'absent': absent,
'excused': excused
}
defaults={"absent": absent, "excused": excused},
)
if remarks:
if personal_note.remarks:
personal_note.remarks += '; %s' % remarks
personal_note.remarks += "; %s" % remarks
else:
personal_note.remarks = remarks
personal_note.save()
......@@ -69,22 +71,25 @@ def get_personal_notes(self, wanted_week: CalendarWeek):
# Find all persons in the associated groups that do not yet have a personal note for this lesson
missing_persons = Person.objects.annotate(
no_personal_notes=~Exists(PersonalNote.objects.filter(
week=wanted_week.week,
lesson_period=self,
person__pk=OuterRef('pk')
))
no_personal_notes=~Exists(
PersonalNote.objects.filter(
week=wanted_week.week, lesson_period=self, person__pk=OuterRef("pk")
)
)
).filter(
member_of__in=Group.objects.filter(pk__in=self.lesson.groups.all()),
is_active=True,
no_personal_notes=True
no_personal_notes=True,
)
# Create all missing personal notes
PersonalNote.objects.bulk_create([
PersonalNote(person=person, lesson_period=self,
week=wanted_week.week) for person in missing_persons
])
PersonalNote.objects.bulk_create(
[
PersonalNote(person=person, lesson_period=self, week=wanted_week.week)
for person in missing_persons
]
)
return PersonalNote.objects.select_related('person').filter(
lesson_period=self, week=wanted_week.week)
return PersonalNote.objects.select_related("person").filter(
lesson_period=self, week=wanted_week.week
)
......@@ -13,10 +13,14 @@ class PersonalNote(models.Model):
absences, excuses and remarks about a student in a single lesson period.
"""
person = models.ForeignKey('core.Person', models.CASCADE, related_name='personal_notes')
person = models.ForeignKey(
"core.Person", models.CASCADE, related_name="personal_notes"
)
week = models.IntegerField()
lesson_period = models.ForeignKey('chronos.LessonPeriod', models.CASCADE, related_name='personal_notes')
lesson_period = models.ForeignKey(
"chronos.LessonPeriod", models.CASCADE, related_name="personal_notes"
)
absent = models.BooleanField(default=False)
late = models.IntegerField(default=0)
......@@ -25,9 +29,15 @@ class PersonalNote(models.Model):
remarks = models.CharField(max_length=200, blank=True)
class Meta:
unique_together = [['lesson_period', 'week', 'person']]
ordering = ['lesson_period__lesson__date_start', 'week', 'lesson_period__period__weekday',
'lesson_period__period__period', 'person__last_name', 'person__first_name']
unique_together = [["lesson_period", "week", "person"]]
ordering = [
"lesson_period__lesson__date_start",
"week",
"lesson_period__period__weekday",
"lesson_period__period__period",
"person__last_name",
"person__first_name",
]
class LessonDocumentation(CRUDMixin):
......@@ -37,27 +47,38 @@ class LessonDocumentation(CRUDMixin):
week = models.IntegerField()
lesson_period = models.ForeignKey(
'chronos.LessonPeriod', models.CASCADE, related_name='documentations')
"chronos.LessonPeriod", models.CASCADE, related_name="documentations"
)
topic = models.CharField(verbose_name=_('Lesson topic'), max_length=200, blank=True)
homework = models.CharField(verbose_name=_('Homework'), max_length=200, blank=True)
topic = models.CharField(verbose_name=_("Lesson topic"), max_length=200, blank=True)
homework = models.CharField(verbose_name=_("Homework"), max_length=200, blank=True)
class Meta:
unique_together = [['lesson_period', 'week']]
ordering = ['lesson_period__lesson__date_start', 'week',
'lesson_period__period__weekday', 'lesson_period__period__period']
unique_together = [["lesson_period", "week"]]
ordering = [
"lesson_period__lesson__date_start",
"week",
"lesson_period__period__weekday",
"lesson_period__period__period",
]
class PersonalNoteFilter(models.Model):
""" A filter definition that can generate statistics on personal note texts. """
identifier = models.CharField(verbose_name=_('Identifier'), max_length=30,
validators=[isidentifier], unique=True)
description = models.CharField(verbose_name=_('Description'), max_length=60,
blank=True, unique=True)
identifier = models.CharField(
verbose_name=_("Identifier"),
max_length=30,
validators=[isidentifier],
unique=True,
)
description = models.CharField(
verbose_name=_("Description"), max_length=60, blank=True, unique=True
)
regex = models.CharField(verbose_name=_('Match expression'), max_length=100,
unique=True)
regex = models.CharField(
verbose_name=_("Match expression"), max_length=100, unique=True
)
class Meta:
ordering = ['identifier']
ordering = ["identifier"]
from django.utils.translation import ugettext_lazy as _
import django_tables2 as tables
from django_tables2.utils import A
class PersonalNoteFilterTable(tables.Table):
class Meta:
attrs = {'class': 'table table-striped table-bordered table-hover table-responsive-xl'}
attrs = {
"class": "table table-striped table-bordered table-hover table-responsive-xl"
}
identifier = tables.Column()
description = tables.Column()
regex = tables.Column()
edit_filter = tables.LinkColumn(
'edit_personal_note_filter', args=[A('id')], text=_('Edit'))
"edit_personal_note_filter", args=[A("id")], text=_("Edit")
)
......@@ -2,24 +2,37 @@ from django.urls import path
from . import views
urlpatterns = [
path('lesson', views.lesson, name='lesson'),
path('lesson/<int:year>/<int:week>/<int:period_id>', views.lesson,
name='lesson_by_week_and_period'),
path('week', views.week_view, name='week_view'),
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'),
path('absence/new', views.register_absence,
name='register_absence'),
path('filters/list', views.list_personal_note_filters,
name='list_personal_note_filters'),
path('filters/create', views.edit_personal_note_filter,
name='create_personal_note_filter'),
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')
path("lesson", views.lesson, name="lesson"),
path(
"lesson/<int:year>/<int:week>/<int:period_id>",
views.lesson,
name="lesson_by_week_and_period",
),
path("week", views.week_view, name="week_view"),
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"
),
path("absence/new", views.register_absence, name="register_absence"),
path(
"filters/list",
views.list_personal_note_filters,
name="list_personal_note_filters",
),
path(
"filters/create",
views.edit_personal_note_filter,
name="create_personal_note_filter",
),
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",
),
]
This diff is collapsed.
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