Newer
Older
context["register_object_table"] = table
return render(request, "alsijil/class_register/person.html", context)
@permission_required("alsijil.register_absence_rule", fn=objectgetter_optional(Person))
def register_absence(request: HttpRequest, id_: int) -> HttpResponse:
person = get_object_or_404(Person, pk=id_)
register_absence_form = RegisterAbsenceForm(request.POST or None)
if request.method == "POST" and register_absence_form.is_valid():
confirmed = request.POST.get("confirmed", "0") == "1"
# Get data from form
# person = register_absence_form.cleaned_data["person"]
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_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)
# Skip holidays if activated
if not get_site_preferences()["alsijil__allow_entries_in_holidays"]:
holiday = Holiday.on_day(day)
if holiday:
continue
with reversion.create_revision() if confirmed else nullcontext():
affected_count += person.mark_absent(
day,
from_period_on_day,
absent,
excused,
excuse_type,
remarks,
to_period_on_day,
dry_run=not confirmed,
)
if not confirmed:
# Show confirmation page
context = {}
context["affected_lessons"] = affected_count
context["person"] = person
context["form_data"] = register_absence_form.cleaned_data
context["form"] = register_absence_form
return render(request, "alsijil/absences/register_confirm.html", context)
else:
messages.success(request, _("The absence has been saved."))
return redirect("overview_person", person.pk)
context["person"] = person
context["register_absence_form"] = register_absence_form
return render(request, "alsijil/absences/register.html", context)
class DeletePersonalNoteView(PermissionRequiredMixin, DetailView):
model = PersonalNote
template_name = "core/pages/delete.html"
def post(self, request, *args, **kwargs):
note = self.get_object()
with reversion.create_revision():
reversion.set_user(request.user)
note.reset_values()
messages.success(request, _("The personal note has been deleted."))
return redirect("overview_person", note.person.pk)
class ExtraMarkListView(PermissionRequiredMixin, SingleTableView):
model = ExtraMark
table_class = ExtraMarkTable
template_name = "alsijil/extra_mark/list.html"
class ExtraMarkCreateView(PermissionRequiredMixin, AdvancedCreateView):
model = ExtraMark
form_class = ExtraMarkForm
template_name = "alsijil/extra_mark/create.html"
success_url = reverse_lazy("extra_marks")
success_message = _("The extra mark has been created.")
class ExtraMarkEditView(PermissionRequiredMixin, AdvancedEditView):
model = ExtraMark
form_class = ExtraMarkForm
template_name = "alsijil/extra_mark/edit.html"
success_url = reverse_lazy("extra_marks")
success_message = _("The extra mark has been saved.")
class ExtraMarkDeleteView(PermissionRequiredMixin, RevisionMixin, AdvancedDeleteView):
"""Delete view for extra marks."""
template_name = "core/pages/delete.html"
success_url = reverse_lazy("extra_marks")
success_message = _("The extra mark has been deleted.")
class ExcuseTypeListView(PermissionRequiredMixin, SingleTableView):
"""Table of all excuse types."""
model = ExcuseType
table_class = ExcuseTypeTable
template_name = "alsijil/excuse_type/list.html"
class ExcuseTypeCreateView(PermissionRequiredMixin, AdvancedCreateView):
"""Create view for excuse types."""
model = ExcuseType
form_class = ExcuseTypeForm
template_name = "alsijil/excuse_type/create.html"
success_url = reverse_lazy("excuse_types")
success_message = _("The excuse type has been created.")
class ExcuseTypeEditView(PermissionRequiredMixin, AdvancedEditView):
"""Edit view for excuse types."""
model = ExcuseType
form_class = ExcuseTypeForm
template_name = "alsijil/excuse_type/edit.html"
success_url = reverse_lazy("excuse_types")
success_message = _("The excuse type has been saved.")
class ExcuseTypeDeleteView(PermissionRequiredMixin, RevisionMixin, AdvancedDeleteView):
"""Delete view for excuse types."""
template_name = "core/pages/delete.html"
success_url = reverse_lazy("excuse_types")
success_message = _("The excuse type has been deleted.")
class GroupRoleListView(PermissionRequiredMixin, SingleTableView):
"""Table of all group roles."""
model = GroupRole
table_class = GroupRoleTable
template_name = "alsijil/group_role/list.html"
@method_decorator(never_cache, name="dispatch")
class GroupRoleCreateView(PermissionRequiredMixin, AdvancedCreateView):
"""Create view for group roles."""
model = GroupRole
form_class = GroupRoleForm
template_name = "alsijil/group_role/create.html"
success_url = reverse_lazy("group_roles")
success_message = _("The group role has been created.")
@method_decorator(never_cache, name="dispatch")
class GroupRoleEditView(PermissionRequiredMixin, AdvancedEditView):
"""Edit view for group roles."""
model = GroupRole
form_class = GroupRoleForm
template_name = "alsijil/group_role/edit.html"
success_url = reverse_lazy("group_roles")
success_message = _("The group role has been saved.")
@method_decorator(never_cache, "dispatch")
class GroupRoleDeleteView(PermissionRequiredMixin, RevisionMixin, AdvancedDeleteView):
"""Delete view for group roles."""
template_name = "core/pages/delete.html"
success_url = reverse_lazy("group_roles")
success_message = _("The group role has been deleted.")
class AssignedGroupRolesView(PermissionRequiredMixin, DetailView):
permission_required = "alsijil.view_assigned_grouproles_rule"
model = Group
template_name = "alsijil/group_role/assigned_list.html"
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
context = super().get_context_data()
today = timezone.now().date()
context["today"] = today
self.roles = GroupRole.objects.with_assignments(today, [self.object])
context["roles"] = self.roles
assignments = (
GroupRoleAssignment.objects.filter(
Q(groups=self.object) | Q(groups__child_groups=self.object)
)
.distinct()
.order_by("-date_start")
)
context["assignments"] = assignments
return context
@method_decorator(never_cache, name="dispatch")
class AssignGroupRoleView(PermissionRequiredMixin, SuccessNextMixin, AdvancedCreateView):
model = GroupRoleAssignment
form_class = AssignGroupRoleForm
permission_required = "alsijil.assign_grouprole_for_group_rule"
template_name = "alsijil/group_role/assign.html"
success_message = _("The group role has been assigned.")
def get_success_url(self) -> str:
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
return reverse("assigned_group_roles", args=[self.group.pk])
def get_permission_object(self):
self.group = get_object_or_404(Group, pk=self.kwargs.get("pk"))
try:
self.role = GroupRole.objects.get(pk=self.kwargs.get("role_pk"))
except GroupRole.DoesNotExist:
self.role = None
return self.group
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs["request"] = self.request
kwargs["initial"] = {"role": self.role, "groups": [self.group]}
return kwargs
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
context = super().get_context_data(**kwargs)
context["role"] = self.role
context["group"] = self.group
return context
@method_decorator(never_cache, name="dispatch")
class AssignGroupRoleMultipleView(PermissionRequiredMixin, SuccessNextMixin, AdvancedCreateView):
model = GroupRoleAssignment
form_class = AssignGroupRoleForm
permission_required = "alsijil.assign_grouprole_for_multiple_rule"
template_name = "alsijil/group_role/assign.html"
success_message = _("The group role has been assigned.")
def get_success_url(self) -> str:
return reverse("assign_group_role_multiple")
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs["request"] = self.request
return kwargs
@method_decorator(never_cache, name="dispatch")
class GroupRoleAssignmentEditView(PermissionRequiredMixin, SuccessNextMixin, AdvancedEditView):
"""Edit view for group role assignments."""
model = GroupRoleAssignment
form_class = GroupRoleAssignmentEditForm
permission_required = "alsijil.edit_grouproleassignment_rule"
template_name = "alsijil/group_role/edit_assignment.html"
success_message = _("The group role assignment has been saved.")
def get_success_url(self) -> str:
pk = self.object.groups.first().pk
return reverse("assigned_group_roles", args=[pk])
@method_decorator(never_cache, "dispatch")
class GroupRoleAssignmentStopView(PermissionRequiredMixin, SuccessNextMixin, DetailView):
model = GroupRoleAssignment
permission_required = "alsijil.stop_grouproleassignment_rule"
def get_success_url(self) -> str:
pk = self.object.groups.first().pk
return reverse("assigned_group_roles", args=[pk])
def get(self, request, *args, **kwargs):
self.object = self.get_object()
if not self.object.date_end:
self.object.date_end = timezone.now().date()
self.object.save()
messages.success(request, _("The group role assignment has been stopped."))
return redirect(self.get_success_url())
@method_decorator(never_cache, "dispatch")
class GroupRoleAssignmentDeleteView(
PermissionRequiredMixin, RevisionMixin, SuccessNextMixin, AdvancedDeleteView
):
"""Delete view for group role assignments."""
model = GroupRoleAssignment
permission_required = "alsijil.delete_grouproleassignment_rule"
template_name = "core/pages/delete.html"
success_message = _("The group role assignment has been deleted.")
def get_success_url(self) -> str:
pk = self.object.groups.first().pk
return reverse("assigned_group_roles", args=[pk])
class AllRegisterObjectsView(PermissionRequiredMixin, View):
"""Provide overview of all register objects for coordinators."""
permission_required = "alsijil.view_register_objects_list_rule"
def get_context_data(self, request):
context = {}
# Filter selectable groups by permissions
groups = Group.objects.all()
if not check_global_permission(request.user, "alsijil.view_full_register"):
allowed_groups = get_objects_for_user(
self.request.user, "core.view_full_register_group", Group
).values_list("pk", flat=True)
groups = groups.filter(Q(parent_groups__in=allowed_groups) | Q(pk__in=allowed_groups))
# Build filter with own form and logic as django-filter can't work with different models
filter_form = FilterRegisterObjectForm(
request, request.GET or None, for_person=False, groups=groups
)
filter_dict = filter_form.cleaned_data if filter_form.is_valid() else {}
filter_dict["groups"] = groups
context["filter_form"] = filter_form
register_objects = generate_list_of_all_register_objects(filter_dict)
self.action_form = RegisterObjectActionForm(request, register_objects, request.POST or None)
context["action_form"] = self.action_form
if register_objects:
self.table = RegisterObjectSelectTable(register_objects)
items_per_page = request.user.person.preferences[
"alsijil__register_objects_table_items_per_page"
]
RequestConfig(request, paginate={"per_page": items_per_page}).configure(self.table)
context["table"] = self.table
return context
def get(self, request: HttpRequest) -> HttpResponse:
context = self.get_context_data(request)
return render(request, "alsijil/class_register/all_objects.html", context)
def post(self, request: HttpRequest):
context = self.get_context_data(request)
if self.action_form.is_valid():
self.action_form.execute()
return render(request, "alsijil/class_register/all_objects.html", context)