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

Add views for assigning subjects and child groups to groups

Necessary for matching method by subjects and parent groups (MySQL importer)
parent 2fca1445
No related branches found
No related tags found
1 merge request!15Add views for assigning subjects to groups
from django_filters import FilterSet, CharFilter
from material import Layout, Row
class GroupFilter(FilterSet):
name = CharFilter(lookup_expr="icontains")
short_name = CharFilter(lookup_expr="icontains")
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form.layout = Layout(Row("name", "short_name"))
......@@ -5,11 +5,38 @@ from constance import config
from material import Fieldset
from aleksis.core.forms import EditGroupForm
from aleksis.core.models import Group
class UntisUploadForm(forms.Form):
untis_xml = forms.FileField(label=_("Untis XML export"))
class GroupSubjectForm(forms.ModelForm):
child_groups = forms.ModelMultipleChoiceField(queryset=Group.objects.all())
class Meta:
model = Group
fields = [
"name",
"short_name",
"untis_subject",
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["name"].widget = forms.HiddenInput()
self.fields["short_name"].widget = forms.HiddenInput()
GroupSubjectFormset = forms.modelformset_factory(
Group, form=GroupSubjectForm, max_num=0, extra=0
)
class ChildGroupsForm(forms.Form):
child_groups = forms.ModelMultipleChoiceField(queryset=Group.objects.all())
if config.UNTIS_IMPORT_MYSQL_USE_COURSE_GROUPS:
EditGroupForm.add_node_to_layout(Fieldset(_("UNTIS import"), "untis_subject"))
......@@ -10,6 +10,24 @@ MENUS = {
"menu_generator.validators.is_superuser",
"aleksis.core.util.core_helpers.has_person",
],
}
},
{
"name": _("Link subjects to groups (for UNTIS MySQL import)"),
"url": "untis_groups_subjects",
"validators": [
"menu_generator.validators.is_authenticated",
"menu_generator.validators.is_superuser",
"aleksis.core.util.core_helpers.has_person",
],
},
{
"name": _("Link child groups to groups (for UNTIS MySQL import)"),
"url": "untis_groups_child_groups",
"validators": [
"menu_generator.validators.is_authenticated",
"menu_generator.validators.is_superuser",
"aleksis.core.util.core_helpers.has_person",
],
},
]
}
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load i18n material_form %}
{% block browser_title %}{% blocktrans %}Assign child groups to groups{% endblocktrans %}{% endblock %}
{% block page_title %}
{% blocktrans %}Assign child groups to groups{% endblocktrans %}
{% endblock %}
{% block content %}
{% if not page %}
<div class="alert info">
<p>
<i class="material-icons left">info</i>
{% blocktrans %}
You can use this to assign child groups to groups. Please use the filters below to select groups you want to
change and click at "Next".
{% endblocktrans %}
</p>
</div>
<form method="get">
{% csrf_token %}
{% form form=filter.form %}{% endform %}
<button type="submit" class="btn green waves-effect waves-light">
<i class="material-icons left">refresh</i>
{% trans "Update selection" %}
</button>
<a href="{% url "untis_groups_child_groups" %}" class="btn red waves-effect waves-light">
<i class="material-icons left">clear</i>
{% trans "Clear all filters" %}
</a>
</form>
<h5>{% trans "Currently selected groups" %}</h5>
{% for group in filter.qs %}
<div class="chip">
{{ group }}
</div>
{% endfor %}
{% if filter.qs %}
<p>
<form method="post">
{% csrf_token %}
<button class="btn btn-primary waves-effect waves-light" type="submit" name="page" value="1">
{% trans "Start assigning child groups for this groups" %}
<i class="material-icons right">arrow_forward</i>
</button>
</form>
</p>
{% else %}
<div class="alert warning">
<p>
<i class="material-icons left">warning</i>
{% blocktrans %}
Please select some groups in order to go on with assigning.
{% endblocktrans %}
</p>
</div>
{% endif %}
{% else %}
<form method="post">
<input type="hidden" name="old_page" value="{{ page.number }}">
<p class="flow-text">
{% trans "Current group:" %} {{ group }}
</p>
<div class="alert warning">
<p>
<i class="material-icons left">warning</i>
{% blocktrans %}
<strong>Please be careful!</strong><br/>
If you click on "Back" or "Next" the current group assignments are not saved.
If you click on save, you will overwrite all existing child group relations for this group with what you
selected on this page.
{% endblocktrans %}
</p>
</div>
<div class="row">
<p class="left">
{% if page.has_previous %}
<button class="btn grey waves-effect waves-light" name="page" value="{{ page.previous_page_number }}">
<i class="material-icons left">arrow_back</i>
{% trans "Back" %}
</button>
{% endif %}
{% if page.has_next %}
<button class="btn grey waves-effect waves-light" type="submit" name="page"
value="{{ page.next_page_number }}">
{% trans "Next" %}
<i class="material-icons right">arrow_forward</i>
</button>
{% endif %}
</p>
<p class="right">
<button class="btn green waves-effect waves-light" type="submit" name="save">
{% trans "Save" %}
<i class="material-icons left">save</i>
</button>
{% if page.has_next %}
<button class="btn green waves-effect waves-light" type="submit" name="save"
value="{{ page.next_page_number }}">
{% trans "Save and next" %}
<i class="material-icons left">save</i>
</button>
{% endif %}
</p>
</div>
{% csrf_token %}
{% include "components/chips.html" with form_field=form.child_groups %}
<p class="left">
{% if page.has_previous %}
<button class="btn grey waves-effect waves-light" name="page" value="{{ page.previous_page_number }}">
<i class="material-icons left">arrow_back</i>
{% trans "Back" %}
</button>
{% endif %}
{% if page.has_next %}
<button class="btn grey waves-effect waves-light" type="submit" name="page"
value="{{ page.next_page_number }}">
{% trans "Next" %}
<i class="material-icons right">arrow_forward</i>
</button>
{% endif %}
</p>
<p class="right">
<button class="btn green waves-effect waves-light" type="submit" name="save">
{% trans "Save" %}
<i class="material-icons left">save</i>
</button>
{% if page.has_next %}
<button class="btn green waves-effect waves-light" type="submit" name="save"
value="{{ page.next_page_number }}">
{% trans "Save and next" %}
<i class="material-icons left">save</i>
</button>
{% endif %}
</p>
</form>
{% endif %}
{% endblock %}
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% load i18n %}
{% block browser_title %}{% blocktrans %}Assign subjects to groups{% endblocktrans %}{% endblock %}
{% block page_title %}
{% blocktrans %}Assign subjects to groups{% endblocktrans %}
{% endblock %}
{% block content %}
<div class="alert info">
<p>
<i class="material-icons left">info</i>
{% blocktrans %}
You can use this form to assign subjects to groups. Please enter the exact names of the subjects as they are
saved in UNTIS (case-insensitive). These values are only used to match course groups while importing from MySQL.
{% endblocktrans %}
</p>
</div>
<div class="alert warning">
<p>
<i class="material-icons left">warning</i>
{% blocktrans %}
If there are more than 100 groups, this table will have multiple pages. That means that you must save your
changes on every page. <strong>Please don't change the page before you saved your changes!</strong>
{% endblocktrans %}
</p>
</div>
<form method="post">
{% csrf_token %}
{{ formset.management_form }}
{% include "core/save_button.html" %}
{% include "components/pagination.html" %}
<table>
<tr>
<th>{% blocktrans %}Group{% endblocktrans %}</th>
<th>{% blocktrans %}Subject{% endblocktrans %}</th>
</tr>
{% for form in formset %}
{{ form.id }}
<tr>
<td>
{{ form.name }} {{ form.short_name }}
{{ form.name.value }} {% if form.short_name.value %}({{ form.short_name.value }}){% endif %}
</td>
<td>{{ form.untis_subject }}</td>
</tr>
{% endfor %}
</table>
{% include "components/pagination.html" %}
{% include "core/save_button.html" %}
<div class="fixed-action-btn">
<button class="btn-floating btn-large green" type="submit">
<i class="large material-icons">save</i>
</button>
</div>
</form>
{% endblock %}
......@@ -4,4 +4,6 @@ from . import views
urlpatterns = [
path("import/xml/", views.xml_import, name="untis_xml_import"),
path("groups_subjects", views.groups_subjects, name="untis_groups_subjects"),
path("groups_child_groups", views.groups_child_groups, name="untis_groups_child_groups"),
]
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from django.http import HttpRequest, HttpResponse
from django.shortcuts import render
from django.utils.translation import gettext as _
from aleksis.core.decorators import admin_required
from aleksis.core.models import Group
from .forms import UntisUploadForm
from .filters import GroupFilter
from .forms import UntisUploadForm, GroupSubjectFormset, ChildGroupsForm
from .util.xml.xml import untis_import_xml
......@@ -24,3 +29,72 @@ def xml_import(request: HttpRequest) -> HttpResponse:
context["upload_form"] = upload_form
return render(request, "untis/xml_import.html", context)
# FIXME: Rule must check if setting is enabled
@admin_required
def groups_subjects(request: HttpRequest) -> HttpResponse:
""" Assign subjects to groups (for matching by MySQL importer) """
context = {}
groups_qs = Group.objects.all()
# Paginate
paginator = Paginator(groups_qs, 100)
page_number = request.GET.get("page")
page = paginator.get_page(page_number)
groups_paged = groups_qs.filter(id__in=[g.id for g in page])
# Create filtered queryset
group_subject_formset = GroupSubjectFormset(
request.POST or None, queryset=groups_paged
)
# Check if form is submitted and valid, then save
if request.method == "POST":
if group_subject_formset.is_valid():
group_subject_formset.save()
messages.success(request, _("Your changes were successfully saved."))
context["formset"] = group_subject_formset
context["page"] = page
context["paginator"] = paginator
return render(request, "untis/groups_subjects.html", context)
@admin_required
def groups_child_groups(request: HttpRequest) -> HttpResponse:
""" Assign child groups to groups (for matching by MySQL importer) """
context = {}
# Apply filter
filter = GroupFilter(request.GET, queryset=Group.objects.all())
context["filter"] = filter
# Paginate
paginator = Paginator(filter.qs, 1)
page_number = request.POST.get("page", request.POST.get("old_page"))
if page_number:
page = paginator.get_page(page_number)
group = page[0]
if "save" in request.POST:
# Save
form = ChildGroupsForm(request.POST)
form.is_valid()
if "child_groups" in form.cleaned_data:
group.child_groups.set(form.cleaned_data["child_groups"])
group.save()
messages.success(request, _("The child groups were successfully saved."))
else:
# Init form
form = ChildGroupsForm(initial={"child_groups": group.child_groups.all()})
context["paginator"] = paginator
context["page"] = page
context["group"] = group
context["form"] = form
return render(request, "untis/groups_child_groups.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