mirror of
https://gitlab.crans.org/bde/nk20
synced 2024-11-26 18:37:12 +00:00
List wei
This commit is contained in:
parent
a186ccbb26
commit
31d2224b8f
@ -15,6 +15,7 @@ from note.api.urls import register_note_urls
|
|||||||
from treasury.api.urls import register_treasury_urls
|
from treasury.api.urls import register_treasury_urls
|
||||||
from logs.api.urls import register_logs_urls
|
from logs.api.urls import register_logs_urls
|
||||||
from permission.api.urls import register_permission_urls
|
from permission.api.urls import register_permission_urls
|
||||||
|
from wei.api.urls import register_wei_urls
|
||||||
|
|
||||||
|
|
||||||
class UserSerializer(serializers.ModelSerializer):
|
class UserSerializer(serializers.ModelSerializer):
|
||||||
@ -78,6 +79,7 @@ register_note_urls(router, 'note')
|
|||||||
register_treasury_urls(router, 'treasury')
|
register_treasury_urls(router, 'treasury')
|
||||||
register_permission_urls(router, 'permission')
|
register_permission_urls(router, 'permission')
|
||||||
register_logs_urls(router, 'logs')
|
register_logs_urls(router, 'logs')
|
||||||
|
register_wei_urls(router, 'wei')
|
||||||
|
|
||||||
app_name = 'api'
|
app_name = 'api'
|
||||||
|
|
||||||
|
0
apps/wei/api/__init__.py
Normal file
0
apps/wei/api/__init__.py
Normal file
17
apps/wei/api/serializers.py
Normal file
17
apps/wei/api/serializers.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from ..models import WEIClub
|
||||||
|
|
||||||
|
|
||||||
|
class WEIClubSerializer(serializers.ModelSerializer):
|
||||||
|
"""
|
||||||
|
REST API Serializer for Clubs.
|
||||||
|
The djangorestframework plugin will analyse the model `WEIClub` and parse all fields in the API.
|
||||||
|
"""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = WEIClub
|
||||||
|
fields = '__all__'
|
11
apps/wei/api/urls.py
Normal file
11
apps/wei/api/urls.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
from .views import WEIClubViewSet
|
||||||
|
|
||||||
|
|
||||||
|
def register_wei_urls(router, path):
|
||||||
|
"""
|
||||||
|
Configure router for Member REST API.
|
||||||
|
"""
|
||||||
|
router.register(path + '/club', WEIClubViewSet)
|
20
apps/wei/api/views.py
Normal file
20
apps/wei/api/views.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
from rest_framework.filters import SearchFilter
|
||||||
|
from api.viewsets import ReadProtectedModelViewSet
|
||||||
|
|
||||||
|
from .serializers import WEIClubSerializer
|
||||||
|
from ..models import WEIClub
|
||||||
|
|
||||||
|
|
||||||
|
class WEIClubViewSet(ReadProtectedModelViewSet):
|
||||||
|
"""
|
||||||
|
REST API View set.
|
||||||
|
The djangorestframework plugin will get all `WEIClub` objects, serialize it to JSON with the given serializer,
|
||||||
|
then render it on /api/wei/club/
|
||||||
|
"""
|
||||||
|
queryset = WEIClub.objects.all()
|
||||||
|
serializer_class = WEIClubSerializer
|
||||||
|
filter_backends = [SearchFilter]
|
||||||
|
search_fields = ['$name', ]
|
76
apps/wei/fixtures/initial.json
Normal file
76
apps/wei/fixtures/initial.json
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"model": "member.club",
|
||||||
|
"pk": 3,
|
||||||
|
"fields": {
|
||||||
|
"name": "A[WEI] from Home",
|
||||||
|
"email": "gc.wei@example.com",
|
||||||
|
"parent_club": 2,
|
||||||
|
"require_memberships": true,
|
||||||
|
"membership_fee_paid": 16500,
|
||||||
|
"membership_fee_unpaid": 9500,
|
||||||
|
"membership_duration": 30,
|
||||||
|
"membership_start": "2019-09-01",
|
||||||
|
"membership_end": "2019-09-16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "wei.weiclub",
|
||||||
|
"pk": 1,
|
||||||
|
"fields": {
|
||||||
|
"club_ptr_id": 3,
|
||||||
|
"year": 2019,
|
||||||
|
"date_start": "2019-09-14",
|
||||||
|
"date_end": "2019-09-16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "note.note",
|
||||||
|
"pk": 7,
|
||||||
|
"fields": {
|
||||||
|
"polymorphic_ctype": [
|
||||||
|
"note",
|
||||||
|
"noteclub"
|
||||||
|
],
|
||||||
|
"balance": 0,
|
||||||
|
"last_negative": null,
|
||||||
|
"is_active": true,
|
||||||
|
"display_image": "pic/default.png",
|
||||||
|
"created_at": "2020-02-20T20:16:14.753Z"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "note.noteclub",
|
||||||
|
"pk": 7,
|
||||||
|
"fields": {
|
||||||
|
"club": 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "note.alias",
|
||||||
|
"pk": 7,
|
||||||
|
"fields": {
|
||||||
|
"name": "A[WEI] from Home",
|
||||||
|
"normalized_name": "aweifromhome",
|
||||||
|
"note": 7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "note.alias",
|
||||||
|
"pk": 8,
|
||||||
|
"fields": {
|
||||||
|
"name": "WEI 2019",
|
||||||
|
"normalized_name": "wei2019",
|
||||||
|
"note": 7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"model": "note.alias",
|
||||||
|
"pk": 9,
|
||||||
|
"fields": {
|
||||||
|
"name": "WEI",
|
||||||
|
"normalized_name": "wei",
|
||||||
|
"note": 7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
@ -1,23 +1,32 @@
|
|||||||
# 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
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from member.models import Role, Club, Membership
|
from member.models import Role, Club, Membership
|
||||||
from note.models import NoteSpecial
|
from note.models import NoteSpecial
|
||||||
|
|
||||||
|
|
||||||
class WEIClub(Club):
|
class WEIClub(Club):
|
||||||
"""
|
"""
|
||||||
|
The WEI is a club. Register to the WEI is equivalent than be member of the club.
|
||||||
"""
|
"""
|
||||||
year = models.PositiveIntegerField(
|
year = models.PositiveIntegerField(
|
||||||
unique=True,
|
unique=True,
|
||||||
verbose_name=_("year"),
|
verbose_name=_("year"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
date_start = models.DateField(
|
||||||
|
verbose_name=_("date start"),
|
||||||
|
)
|
||||||
|
|
||||||
|
date_end = models.DateField(
|
||||||
|
verbose_name=_("date end"),
|
||||||
|
)
|
||||||
|
|
||||||
def update_membership_dates(self):
|
def update_membership_dates(self):
|
||||||
"""
|
"""
|
||||||
We can't join the WEI next years.
|
We can't join the WEI next years.
|
||||||
@ -84,6 +93,8 @@ class WEIRole(Role):
|
|||||||
bus = models.ForeignKey(
|
bus = models.ForeignKey(
|
||||||
Bus,
|
Bus,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
|
null=True,
|
||||||
|
default=None,
|
||||||
related_name="roles",
|
related_name="roles",
|
||||||
verbose_name=_("bus"),
|
verbose_name=_("bus"),
|
||||||
)
|
)
|
||||||
|
25
apps/wei/tables.py
Normal file
25
apps/wei/tables.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
import django_tables2 as tables
|
||||||
|
from django.urls import reverse_lazy
|
||||||
|
|
||||||
|
from wei.models import WEIClub
|
||||||
|
|
||||||
|
|
||||||
|
class WEITable(tables.Table):
|
||||||
|
"""
|
||||||
|
List all clubs.
|
||||||
|
"""
|
||||||
|
class Meta:
|
||||||
|
attrs = {
|
||||||
|
'class': 'table table-condensed table-striped table-hover'
|
||||||
|
}
|
||||||
|
model = WEIClub
|
||||||
|
template_name = 'django_tables2/bootstrap4.html'
|
||||||
|
fields = ('name', 'year', 'date_start', 'date_end',)
|
||||||
|
row_attrs = {
|
||||||
|
'class': 'table-row',
|
||||||
|
'id': lambda record: "row-" + str(record.pk),
|
||||||
|
'data-href': lambda record: reverse_lazy('member:club_detail', args=(record.pk,))
|
||||||
|
}
|
@ -3,7 +3,10 @@
|
|||||||
|
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
|
from .views import WEIListView
|
||||||
|
|
||||||
|
|
||||||
app_name = 'wei'
|
app_name = 'wei'
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
path('list/', WEIListView.as_view(), name="wei_list"),
|
||||||
]
|
]
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
# 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 django.shortcuts import render
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
|
from django_tables2 import SingleTableView
|
||||||
|
from permission.views import ProtectQuerysetMixin
|
||||||
|
from wei.models import WEIClub
|
||||||
|
|
||||||
|
from .tables import WEITable
|
||||||
|
|
||||||
|
|
||||||
|
class WEIListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
|
||||||
|
"""
|
||||||
|
List existing WEI
|
||||||
|
"""
|
||||||
|
model = WEIClub
|
||||||
|
table_class = WEITable
|
||||||
|
@ -312,7 +312,7 @@ function in_validate(id, validated) {
|
|||||||
else
|
else
|
||||||
invalidity_reason = null;
|
invalidity_reason = null;
|
||||||
|
|
||||||
$("#validate_" + id).html("<strong style=\"font-size: 16pt;\">⟳ ...</strong>");
|
$("#validate_" + id).html("<i class='fa fa-spinner'></i>");
|
||||||
|
|
||||||
// Perform a PATCH request to the API in order to update the transaction
|
// Perform a PATCH request to the API in order to update the transaction
|
||||||
// If the user has insuffisent rights, an error message will appear
|
// If the user has insuffisent rights, an error message will appear
|
||||||
|
@ -108,9 +108,12 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% if "treasury.invoice"|not_empty_model_change_list %}
|
{% if "treasury.invoice"|not_empty_model_change_list %}
|
||||||
<li class="nav-item active">
|
<li class="nav-item active">
|
||||||
<a class="nav-link" href="{% url 'treasury:invoice_list' %}"><i class="fa fa-money"></i>{% trans 'Treasury' %} </a>
|
<a class="nav-link" href="{% url 'treasury:invoice_list' %}"><i class="fa fa-money"></i> {% trans 'Treasury' %}</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<li class="nav-item active">
|
||||||
|
<a class="nav-link" href="{% url 'wei:wei_list' %}"><i class="fa fa-bus"></i> {% trans 'WEI' %}</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="navbar-nav ml-auto">
|
<ul class="navbar-nav ml-auto">
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
|
@ -43,8 +43,8 @@
|
|||||||
<dt class="col-xl-6"><a href="{% url 'member:club_alias' club.pk %}">{% trans 'aliases'|capfirst %}</a></dt>
|
<dt class="col-xl-6"><a href="{% url 'member:club_alias' club.pk %}">{% trans 'aliases'|capfirst %}</a></dt>
|
||||||
<dd class="col-xl-6 text-truncate">{{ object.note.alias_set.all|join:", " }}</dd>
|
<dd class="col-xl-6 text-truncate">{{ object.note.alias_set.all|join:", " }}</dd>
|
||||||
|
|
||||||
<dt class="col-xl-3">{% trans 'email'|capfirst %}</dt>
|
<dt class="col-xl-4">{% trans 'email'|capfirst %}</dt>
|
||||||
<dd class="col-xl-9"><a href="mailto:{{ club.email }}">{{ club.email }}</a></dd>
|
<dd class="col-xl-8"><a href="mailto:{{ club.email }}">{{ club.email }}</a></dd>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer text-center">
|
<div class="card-footer text-center">
|
||||||
|
70
templates/wei/weiclub_list.html
Normal file
70
templates/wei/weiclub_list.html
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% load render_table from django_tables2 %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="row justify-content-center mb-4">
|
||||||
|
<div class="col-md-10 text-center">
|
||||||
|
<h4>
|
||||||
|
{% trans "search WEI" %}
|
||||||
|
</h4>
|
||||||
|
<input class="form-control mx-auto w-25" type="text" onkeyup="search_field_moved()" id="search_field"/>
|
||||||
|
<hr>
|
||||||
|
<a class="btn btn-primary text-center my-4" href="{% url 'member:club_create' %}">{% trans "Create WEI" %}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<div class="card card-border shadow">
|
||||||
|
<div class="card-header text-center">
|
||||||
|
<h5> {% trans "WEI listing "%}</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body px-0 py-0" id="club_table">
|
||||||
|
{% render_table table %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
{% block extrajavascript %}
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
function getInfo() {
|
||||||
|
var asked = $("#search_field").val();
|
||||||
|
/* on ne fait la requête que si on a au moins un caractère pour chercher */
|
||||||
|
var sel = $(".table-row");
|
||||||
|
if (asked.length >= 1) {
|
||||||
|
$.getJSON("/api/wei/club/?format=json&search="+asked, function(buttons){
|
||||||
|
let selected_id = buttons.results.map((a => "#row-"+a.id));
|
||||||
|
$(".table-row,"+selected_id.join()).show();
|
||||||
|
$(".table-row").not(selected_id.join()).hide();
|
||||||
|
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
// show everything
|
||||||
|
$('table tr').show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var timer;
|
||||||
|
var timer_on;
|
||||||
|
/* Fontion appelée quand le texte change (délenche le timer) */
|
||||||
|
function search_field_moved(secondfield) {
|
||||||
|
if (timer_on) { // Si le timer a déjà été lancé, on réinitialise le compteur.
|
||||||
|
clearTimeout(timer);
|
||||||
|
timer = setTimeout("getInfo(" + secondfield + ")", 300);
|
||||||
|
}
|
||||||
|
else { // Sinon, on le lance et on enregistre le fait qu'il tourne.
|
||||||
|
timer = setTimeout("getInfo(" + secondfield + ")", 300);
|
||||||
|
timer_on = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clickable row
|
||||||
|
$(document).ready(function($) {
|
||||||
|
$(".table-row").click(function() {
|
||||||
|
window.document.location = $(this).data("href");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
2
tox.ini
2
tox.ini
@ -30,7 +30,7 @@ deps =
|
|||||||
pep8-naming
|
pep8-naming
|
||||||
pyflakes
|
pyflakes
|
||||||
commands =
|
commands =
|
||||||
flake8 apps/activity apps/api apps/logs apps/member apps/note apps/permission apps/treasury
|
flake8 apps/activity apps/api apps/logs apps/member apps/note apps/permission apps/treasury apps/wei
|
||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
# Ignore too many errors, should be reduced in the future
|
# Ignore too many errors, should be reduced in the future
|
||||||
|
Loading…
Reference in New Issue
Block a user