mirror of https://gitlab.crans.org/bde/nk20
Add a bus
This commit is contained in:
parent
6242e316ae
commit
822853be66
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from ..models import WEIClub
|
from ..models import WEIClub, Bus, BusTeam
|
||||||
|
|
||||||
|
|
||||||
class WEIClubSerializer(serializers.ModelSerializer):
|
class WEIClubSerializer(serializers.ModelSerializer):
|
||||||
|
@ -15,3 +15,25 @@ class WEIClubSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = WEIClub
|
model = WEIClub
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class BusSerializer(serializers.ModelSerializer):
|
||||||
|
"""
|
||||||
|
REST API Serializer for Bus.
|
||||||
|
The djangorestframework plugin will analyse the model `Bus` and parse all fields in the API.
|
||||||
|
"""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Bus
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class BusTeamSerializer(serializers.ModelSerializer):
|
||||||
|
"""
|
||||||
|
REST API Serializer for Bus teams.
|
||||||
|
The djangorestframework plugin will analyse the model `BusTeam` and parse all fields in the API.
|
||||||
|
"""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = BusTeam
|
||||||
|
fields = '__all__'
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
from .views import WEIClubViewSet
|
from .views import WEIClubViewSet, BusViewSet, BusTeamViewSet
|
||||||
|
|
||||||
|
|
||||||
def register_wei_urls(router, path):
|
def register_wei_urls(router, path):
|
||||||
"""
|
"""
|
||||||
Configure router for Member REST API.
|
Configure router for Member REST API.
|
||||||
"""
|
"""
|
||||||
router.register(path + '/club/', WEIClubViewSet)
|
router.register(path + '/club', WEIClubViewSet)
|
||||||
|
router.register(path + '/bus', BusViewSet)
|
||||||
|
router.register(path + '/team', BusTeamViewSet)
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
from rest_framework.filters import SearchFilter
|
from rest_framework.filters import SearchFilter
|
||||||
from api.viewsets import ReadProtectedModelViewSet
|
from api.viewsets import ReadProtectedModelViewSet
|
||||||
|
|
||||||
from .serializers import WEIClubSerializer
|
from .serializers import WEIClubSerializer, BusSerializer, BusTeamSerializer
|
||||||
from ..models import WEIClub
|
from ..models import WEIClub, Bus, BusTeam
|
||||||
|
|
||||||
|
|
||||||
class WEIClubViewSet(ReadProtectedModelViewSet):
|
class WEIClubViewSet(ReadProtectedModelViewSet):
|
||||||
|
@ -18,3 +18,27 @@ class WEIClubViewSet(ReadProtectedModelViewSet):
|
||||||
serializer_class = WEIClubSerializer
|
serializer_class = WEIClubSerializer
|
||||||
filter_backends = [SearchFilter]
|
filter_backends = [SearchFilter]
|
||||||
search_fields = ['$name', ]
|
search_fields = ['$name', ]
|
||||||
|
|
||||||
|
|
||||||
|
class BusViewSet(ReadProtectedModelViewSet):
|
||||||
|
"""
|
||||||
|
REST API View set.
|
||||||
|
The djangorestframework plugin will get all `Bus` objects, serialize it to JSON with the given serializer,
|
||||||
|
then render it on /api/wei/bus/
|
||||||
|
"""
|
||||||
|
queryset = Bus.objects.all()
|
||||||
|
serializer_class = BusSerializer
|
||||||
|
filter_backends = [SearchFilter]
|
||||||
|
search_fields = ['$name', ]
|
||||||
|
|
||||||
|
|
||||||
|
class BusTeamViewSet(ReadProtectedModelViewSet):
|
||||||
|
"""
|
||||||
|
REST API View set.
|
||||||
|
The djangorestframework plugin will get all `BusTeam` objects, serialize it to JSON with the given serializer,
|
||||||
|
then render it on /api/wei/team/
|
||||||
|
"""
|
||||||
|
queryset = BusTeam.objects.all()
|
||||||
|
serializer_class = BusTeamSerializer
|
||||||
|
filter_backends = [SearchFilter]
|
||||||
|
search_fields = ['$name', ]
|
||||||
|
|
|
@ -6,7 +6,7 @@ from django.contrib.auth.models import User
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from note_kfet.inputs import AmountInput, DatePickerInput, Autocomplete
|
from note_kfet.inputs import AmountInput, DatePickerInput, Autocomplete
|
||||||
|
|
||||||
from .models import WEIClub, WEIRegistration
|
from .models import WEIClub, WEIRegistration, Bus
|
||||||
|
|
||||||
|
|
||||||
class WEIForm(forms.ModelForm):
|
class WEIForm(forms.ModelForm):
|
||||||
|
@ -43,3 +43,33 @@ class WEIRegistrationForm(forms.ModelForm):
|
||||||
),
|
),
|
||||||
"birth_date": DatePickerInput(),
|
"birth_date": DatePickerInput(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class BusForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Bus
|
||||||
|
fields = '__all__'
|
||||||
|
widgets = {
|
||||||
|
"wei": Autocomplete(
|
||||||
|
WEIClub,
|
||||||
|
attrs={
|
||||||
|
'api_url': '/api/wei/club/',
|
||||||
|
'placeholder': 'WEI ...',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class BusTeamForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Bus
|
||||||
|
fields = '__all__'
|
||||||
|
widgets = {
|
||||||
|
"bus": Autocomplete(
|
||||||
|
Bus,
|
||||||
|
attrs={
|
||||||
|
'api_url': '/api/wei/bus/',
|
||||||
|
'placeholder': 'Bus ...',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ from django.urls import reverse_lazy
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django_tables2 import A
|
from django_tables2 import A
|
||||||
|
|
||||||
from .models import WEIClub, WEIRegistration
|
from .models import WEIClub, WEIRegistration, Bus, BusTeam
|
||||||
|
|
||||||
|
|
||||||
class WEITable(tables.Table):
|
class WEITable(tables.Table):
|
||||||
|
@ -71,13 +71,54 @@ class WEIRegistrationTable(tables.Table):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def render_is_first_year(self, value):
|
||||||
|
return _("yes") if value else _("no")
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
attrs = {
|
attrs = {
|
||||||
'class': 'table table-condensed table-striped table-hover'
|
'class': 'table table-condensed table-striped table-hover'
|
||||||
}
|
}
|
||||||
model = WEIRegistration
|
model = WEIRegistration
|
||||||
template_name = 'django_tables2/bootstrap4.html'
|
template_name = 'django_tables2/bootstrap4.html'
|
||||||
fields = ('user',)
|
fields = ('user', 'is_first_year',)
|
||||||
|
row_attrs = {
|
||||||
|
'class': 'table-row',
|
||||||
|
'id': lambda record: "row-" + str(record.pk),
|
||||||
|
'data-href': lambda record: record.pk
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class BusTable(tables.Table):
|
||||||
|
class Meta:
|
||||||
|
attrs = {
|
||||||
|
'class': 'table table-condensed table-striped table-hover'
|
||||||
|
}
|
||||||
|
model = Bus
|
||||||
|
template_name = 'django_tables2/bootstrap4.html'
|
||||||
|
fields = ('name', 'teams',)
|
||||||
|
row_attrs = {
|
||||||
|
'class': 'table-row',
|
||||||
|
'id': lambda record: "row-" + str(record.pk),
|
||||||
|
'data-href': lambda record: record.pk
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class BusTeamTable(tables.Table):
|
||||||
|
color = tables.Column(
|
||||||
|
attrs={
|
||||||
|
"td": {
|
||||||
|
"style": lambda record: "background-color: #" + "".format(record.color) + ";"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
attrs = {
|
||||||
|
'class': 'table table-condensed table-striped table-hover'
|
||||||
|
}
|
||||||
|
model = BusTeam
|
||||||
|
template_name = 'django_tables2/bootstrap4.html'
|
||||||
|
fields = ('name', 'color', 'team',)
|
||||||
row_attrs = {
|
row_attrs = {
|
||||||
'class': 'table-row',
|
'class': 'table-row',
|
||||||
'id': lambda record: "row-" + str(record.pk),
|
'id': lambda record: "row-" + str(record.pk),
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
|
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from .views import WEIListView, WEICreateView, WEIDetailView, WEIUpdateView, WEIRegisterView, WEIUpdateRegistrationView
|
from .views import WEIListView, WEICreateView, WEIDetailView, WEIUpdateView, BusCreateView,\
|
||||||
|
WEIRegisterView, WEIUpdateRegistrationView
|
||||||
|
|
||||||
|
|
||||||
app_name = 'wei'
|
app_name = 'wei'
|
||||||
|
@ -12,6 +13,7 @@ urlpatterns = [
|
||||||
path('create/', WEICreateView.as_view(), name="wei_create"),
|
path('create/', WEICreateView.as_view(), name="wei_create"),
|
||||||
path('detail/<int:pk>/', WEIDetailView.as_view(), name="wei_detail"),
|
path('detail/<int:pk>/', WEIDetailView.as_view(), name="wei_detail"),
|
||||||
path('update/<int:pk>/', WEIUpdateView.as_view(), name="wei_update"),
|
path('update/<int:pk>/', WEIUpdateView.as_view(), name="wei_update"),
|
||||||
|
path('add-bus/<int:pk>/', BusCreateView.as_view(), name="add_bus"),
|
||||||
path('register/<int:wei_pk>/', WEIRegisterView.as_view(), name="wei_register"),
|
path('register/<int:wei_pk>/', WEIRegisterView.as_view(), name="wei_register"),
|
||||||
path('edit_registration/<int:pk>/', WEIUpdateRegistrationView.as_view(), name="wei_update_registration"),
|
path('edit-registration/<int:pk>/', WEIUpdateRegistrationView.as_view(), name="wei_update_registration"),
|
||||||
]
|
]
|
||||||
|
|
|
@ -16,9 +16,9 @@ from note.tables import HistoryTable
|
||||||
from permission.backends import PermissionBackend
|
from permission.backends import PermissionBackend
|
||||||
from permission.views import ProtectQuerysetMixin
|
from permission.views import ProtectQuerysetMixin
|
||||||
|
|
||||||
from .models import WEIClub, WEIRegistration, WEIMembership
|
from .models import WEIClub, WEIRegistration, WEIMembership, Bus
|
||||||
from .forms import WEIForm, WEIRegistrationForm
|
from .forms import WEIForm, WEIRegistrationForm, BusForm
|
||||||
from .tables import WEITable, WEIRegistrationTable
|
from .tables import WEITable, WEIRegistrationTable, BusTable
|
||||||
|
|
||||||
|
|
||||||
class WEIListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
|
class WEIListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
|
||||||
|
@ -91,6 +91,11 @@ class WEIDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
|
||||||
pre_registrations_table.paginate(per_page=20, page=self.request.GET.get('membership-page', 1))
|
pre_registrations_table.paginate(per_page=20, page=self.request.GET.get('membership-page', 1))
|
||||||
context['pre_registrations'] = pre_registrations_table
|
context['pre_registrations'] = pre_registrations_table
|
||||||
|
|
||||||
|
buses = Bus.objects.filter(PermissionBackend.filter_queryset(self.request.user, Bus, "view"))\
|
||||||
|
.filter(wei=self.object)
|
||||||
|
bus_table = BusTable(data=buses, prefix="bus-")
|
||||||
|
context['buses'] = bus_table
|
||||||
|
|
||||||
# Check if the user has the right to create a membership, to display the button.
|
# Check if the user has the right to create a membership, to display the button.
|
||||||
empty_membership = Membership(
|
empty_membership = Membership(
|
||||||
club=club,
|
club=club,
|
||||||
|
@ -117,6 +122,28 @@ class WEIUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
|
||||||
return reverse_lazy("wei:wei_detail", kwargs={"pk": self.object.pk})
|
return reverse_lazy("wei:wei_detail", kwargs={"pk": self.object.pk})
|
||||||
|
|
||||||
|
|
||||||
|
class BusCreateView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
|
||||||
|
"""
|
||||||
|
Create Bus
|
||||||
|
"""
|
||||||
|
model = Bus
|
||||||
|
form_class = BusForm
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["club"] = WEIClub.objects.get(pk=self.kwargs["pk"])
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_form(self, form_class=None):
|
||||||
|
form = super().get_form(form_class)
|
||||||
|
form.fields["wei"].initial = WEIClub.objects.get(pk=self.kwargs["pk"])
|
||||||
|
return form
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
self.object.refresh_from_db()
|
||||||
|
return reverse_lazy("wei:wei_detail", kwargs={"pk": self.object.wei.pk})
|
||||||
|
|
||||||
|
|
||||||
class WEIRegisterView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
|
class WEIRegisterView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
|
||||||
"""
|
"""
|
||||||
Register to the WEI
|
Register to the WEI
|
||||||
|
|
|
@ -19,9 +19,11 @@
|
||||||
|
|
||||||
{% block extrajavascript %}
|
{% block extrajavascript %}
|
||||||
<script>
|
<script>
|
||||||
|
{% if object %}
|
||||||
function refreshHistory() {
|
function refreshHistory() {
|
||||||
$("#history_list").load("{% url 'member:user_detail' pk=object.pk %} #history_list");
|
$("#history_list").load("{% url 'member:user_detail' pk=object.pk %} #history_list");
|
||||||
$("#profile_infos").load("{% url 'member:user_detail' pk=object.pk %} #profile_infos");
|
$("#profile_infos").load("{% url 'member:user_detail' pk=object.pk %} #profile_infos");
|
||||||
}
|
}
|
||||||
|
{% endif %}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
{% extends "member/noteowner_detail.html" %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block profile_info %}
|
||||||
|
{% if club %}
|
||||||
|
{% include "wei/weiclub_info.html" %}
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block profile_content %}
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
<button class="btn btn-primary" type="submit">{% trans "Submit" %}</button>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
|
@ -1,11 +1,17 @@
|
||||||
{% extends "base.html" %}
|
{% extends "member/noteowner_detail.html" %}
|
||||||
{% load static %}
|
|
||||||
{% load i18n %}
|
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
{% block content %}
|
{% load i18n %}
|
||||||
<form method="post">
|
|
||||||
{% csrf_token %}
|
{% block profile_info %}
|
||||||
{{ form|crispy }}
|
{% if club %}
|
||||||
<button class="btn btn-primary" type="submit">{% trans "Submit" %}</button>
|
{% include "wei/weiclub_info.html" %}
|
||||||
</form>
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block profile_content %}
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
<button class="btn btn-primary" type="submit">{% trans "Submit" %}</button>
|
||||||
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -37,12 +37,12 @@
|
||||||
|
|
||||||
{% if "note.view_note"|has_perm:club.note %}
|
{% if "note.view_note"|has_perm:club.note %}
|
||||||
<dt class="col-xl-6">{% trans 'balance'|capfirst %}</dt>
|
<dt class="col-xl-6">{% trans 'balance'|capfirst %}</dt>
|
||||||
<dd class="col-xl-6">{{ object.note.balance | pretty_money }}</dd>
|
<dd class="col-xl-6">{{ club.note.balance | pretty_money }}</dd>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if "note.change_alias"|has_perm:club.note.alias_set.first %}
|
{% if "note.change_alias"|has_perm:club.note.alias_set.first %}
|
||||||
<dt class="col-xl-4"><a href="{% url 'member:club_alias' club.pk %}">{% trans 'aliases'|capfirst %}</a></dt>
|
<dt class="col-xl-4"><a href="{% url 'member:club_alias' club.pk %}">{% trans 'aliases'|capfirst %}</a></dt>
|
||||||
<dd class="col-xl-8 text-truncate">{{ object.note.alias_set.all|join:", " }}</dd>
|
<dd class="col-xl-8 text-truncate">{{ club.note.alias_set.all|join:", " }}</dd>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<dt class="col-xl-4">{% trans 'email'|capfirst %}</dt>
|
<dt class="col-xl-4">{% trans 'email'|capfirst %}</dt>
|
||||||
|
@ -56,6 +56,9 @@
|
||||||
{% if ".change_"|has_perm:club %}
|
{% if ".change_"|has_perm:club %}
|
||||||
<a class="btn btn-primary btn-sm my-1" href="{% url 'wei:wei_update' pk=club.pk %}"> {% trans "Edit" %}</a>
|
<a class="btn btn-primary btn-sm my-1" href="{% url 'wei:wei_update' pk=club.pk %}"> {% trans "Edit" %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if True %}
|
||||||
|
<a class="btn btn-primary btn-sm my-1" href="{% url 'wei:add_bus' pk=club.pk %}"> {% trans "Add bus" %}</a>
|
||||||
|
{% endif %}
|
||||||
{% url 'wei:wei_detail' club.pk as club_detail_url %}
|
{% url 'wei:wei_detail' club.pk as club_detail_url %}
|
||||||
{%if request.path_info != club_detail_url %}
|
{%if request.path_info != club_detail_url %}
|
||||||
<a class="btn btn-primary btn-sm my-1" href="{{ club_detail_url }}">{% trans 'View WEI' %}</a>
|
<a class="btn btn-primary btn-sm my-1" href="{{ club_detail_url }}">{% trans 'View WEI' %}</a>
|
||||||
|
|
|
@ -59,6 +59,19 @@
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
{% if buses.data or True %}
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header position-relative" id="clubListHeading">
|
||||||
|
<a class="btn btn-link stretched-link font-weight-bold">
|
||||||
|
<i class="fa fa-bus"></i> {% trans "Buses" %}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% render_table buses %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if member_list.data %}
|
{% if member_list.data %}
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header position-relative" id="clubListHeading">
|
<div class="card-header position-relative" id="clubListHeading">
|
||||||
|
|
Loading…
Reference in New Issue