mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-10-30 07:19:56 +01:00 
			
		
		
		
	List wei
This commit is contained in:
		| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user