mirror of
https://github.com/nanoy42/coope
synced 2024-11-22 11:23:11 +00:00
Merge branch 'release-3.3.0' into 'master'
Release 3.3.0 Closes #29, #30, #31, #32, #34, #35, #36, #37, #38, and #39 See merge request coope/coopev3!7
This commit is contained in:
commit
9364838c34
50 changed files with 3542 additions and 230 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -42,3 +42,4 @@ tags
|
|||
.vscode
|
||||
venv
|
||||
static/
|
||||
Pipfile
|
||||
|
|
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -1,3 +1,15 @@
|
|||
## v3.3.0
|
||||
* Ajout d'icônes
|
||||
* Le . est utilisé pour les décimaux
|
||||
* Ajout de liens vers les profils de produits et utilisateurs
|
||||
* Ajout de cotisations dans les transactions
|
||||
* Ajout d'une page d'accueil. Les pressions du moment y sont affichées
|
||||
* Belles couleurs sur le diagramme
|
||||
* Verouillage automatique de la caisse
|
||||
* Classement par produit
|
||||
* Fix invalidation
|
||||
* Recherche plus intuitive (le startswith devient contains)
|
||||
* Easter egg sur 404
|
||||
## v3.2.2
|
||||
* Fix cotisation cancer
|
||||
## v3.2.1
|
||||
|
|
|
@ -39,3 +39,9 @@ def global_message():
|
|||
gp,_ = GeneralPreferences.objects.get_or_create(pk=1)
|
||||
messages = gp.global_message.split("\n")
|
||||
return random.choice(messages)
|
||||
|
||||
@register.simple_tag
|
||||
def logout_time():
|
||||
gp, _ = GeneralPreferences.objects.get_or_create(pk=1)
|
||||
logout_time = gp.automatic_logout_time
|
||||
return logout_time
|
|
@ -20,6 +20,8 @@ from . import views
|
|||
|
||||
urlpatterns = [
|
||||
path('', views.home, name="home"),
|
||||
path('home', views.homepage, name="homepage"),
|
||||
path('coope-runner', views.coope_runner, name="coope-runner"),
|
||||
path('admin/doc/', include('django.contrib.admindocs.urls')),
|
||||
path('admin/', admin.site.urls),
|
||||
path('users/', include('users.urls')),
|
||||
|
|
|
@ -1,11 +1,22 @@
|
|||
from django.shortcuts import redirect
|
||||
from django.shortcuts import redirect, render
|
||||
from django.urls import reverse
|
||||
|
||||
from preferences.models import GeneralPreferences
|
||||
from gestion.models import Keg
|
||||
|
||||
def home(request):
|
||||
if request.user.is_authenticated:
|
||||
if(request.user.has_perm('gestion.can_manage')):
|
||||
return redirect(reverse('gestion:manage'))
|
||||
else:
|
||||
return redirect(reverse('users:profile', kwargs={'pk': request.user.pk}))
|
||||
return redirect(reverse('homepage'))
|
||||
else:
|
||||
return redirect(reverse('users:login'))
|
||||
|
||||
def homepage(request):
|
||||
gp, _ = GeneralPreferences.objects.get_or_create(pk=1)
|
||||
kegs = Keg.objects.filter(is_active=True)
|
||||
return render(request, "home.html", {"home_text": gp.home_text, "kegs": kegs})
|
||||
|
||||
def coope_runner(request):
|
||||
return render(request, "coope-runner.html")
|
||||
|
|
|
@ -16,20 +16,21 @@ class ReloadForm(forms.ModelForm):
|
|||
class Meta:
|
||||
model = Reload
|
||||
fields = ("customer", "amount", "PaymentMethod")
|
||||
widgets = {'customer': autocomplete.ModelSelect2(url='users:active-users-autocomplete', attrs={'data-minimum-input-length':2})}
|
||||
widgets = {'customer': autocomplete.ModelSelect2(url='users:active-users-autocomplete', attrs={'data-minimum-input-length':2}), 'amount': forms.TextInput}
|
||||
|
||||
|
||||
class RefundForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Refund
|
||||
fields = ("customer", "amount")
|
||||
widgets = {'customer': autocomplete.ModelSelect2(url='users:active-users-autocomplete', attrs={'data-minimum-input-length':2})}
|
||||
widgets = {'customer': autocomplete.ModelSelect2(url='users:active-users-autocomplete', attrs={'data-minimum-input-length':2}), 'amount': forms.TextInput}
|
||||
|
||||
|
||||
class ProductForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Product
|
||||
fields = "__all__"
|
||||
widgets = {'amount': forms.TextInput}
|
||||
|
||||
class KegForm(forms.ModelForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -41,11 +42,13 @@ class KegForm(forms.ModelForm):
|
|||
class Meta:
|
||||
model = Keg
|
||||
exclude = ("is_active", )
|
||||
widgets = {'amount': forms.TextInput}
|
||||
|
||||
class MenuForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Menu
|
||||
fields = "__all__"
|
||||
widgets = {'amount': forms.TextInput}
|
||||
|
||||
class SearchProductForm(forms.Form):
|
||||
product = forms.ModelChoiceField(queryset=Product.objects.all(), required=True, label="Produit", widget=autocomplete.ModelSelect2(url='gestion:products-autocomplete', attrs={'data-minimum-input-length':2}))
|
||||
|
|
|
@ -45,6 +45,22 @@ class Product(models.Model):
|
|||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def user_ranking(self, pk):
|
||||
user = User.objects.get(pk=pk)
|
||||
consumptions = ConsumptionHistory.objects.filter(customer=user).filter(product=self)
|
||||
# add menu
|
||||
nb = 0
|
||||
for consumption in consumptions:
|
||||
nb += consumption.quantity
|
||||
return (user, nb)
|
||||
|
||||
@property
|
||||
def ranking(self):
|
||||
users = User.objects.all()
|
||||
ranking = [self.user_ranking(user.pk) for user in users]
|
||||
ranking.sort(key=lambda x:x[1], reverse=True)
|
||||
return ranking[0:25]
|
||||
|
||||
|
||||
def isPinte(id):
|
||||
product = Product.objects.get(id=id)
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
<h2>Liste des fûts actifs</h2>
|
||||
</header>
|
||||
{% if perms.gestion.add_keg %}
|
||||
<a class="button" href="{% url 'gestion:addKeg' %}">Créer un fût</a>
|
||||
<a class="button" href="{% url 'gestion:addKeg' %}"><i class="fa fa-plus-square"></i> Créer un fût</a>
|
||||
{% endif %}
|
||||
{% if perms.gestion.open_keg %}
|
||||
<a class="button" href="{% url 'gestion:openKeg' %}">Percuter un fût</a>
|
||||
<a class="button" href="{% url 'gestion:openKeg' %}"><i class="fa fa-fill-drip"></i> Percuter un fût</a>
|
||||
{% endif %}
|
||||
{% if perms.gestion.close_keg %}
|
||||
<a class="button" href="{% url 'gestion:closeKeg' %}">Fermer un fût</a>
|
||||
<a class="button" href="{% url 'gestion:closeKeg' %}"><i class="fa fa-fill"></i> Fermer un fût</a>
|
||||
{% endif %}
|
||||
<br><br>
|
||||
<div class="table-wrapper">
|
||||
|
@ -33,6 +33,7 @@
|
|||
<th>Quantité vendue</th>
|
||||
<th>Montant vendu</th>
|
||||
<th>Prix du fût</th>
|
||||
<th>Degré</th>
|
||||
<th>Historique</th>
|
||||
<th>Administrer</th>
|
||||
</tr>
|
||||
|
@ -47,8 +48,9 @@
|
|||
<td>{{ kegH.quantitySold }} L</td>
|
||||
<td>{{ kegH.amountSold }} €</td>
|
||||
<td>{{ kegH.keg.amount }} €</td>
|
||||
<td>{{ kegH.keg.pinte.deg }}°</td>
|
||||
<td><a href="{% url 'gestion:kegH' kegH.keg.pk %}">Voir</a></td>
|
||||
<td>{% if perms.gestion.close_keg %}<a href="{% url 'gestion:closeDirectKeg' kegH.keg.pk %}" class="button small">Fermer</a> {% endif %}{% if perms.gestion.change_keg %}<a href="{% url 'gestion:editKeg' kegH.keg.pk %}" class="button small">Modifier</a>{% endif %}</td>
|
||||
<td>{% if perms.gestion.close_keg %}<a href="{% url 'gestion:closeDirectKeg' kegH.keg.pk %}" class="button small"><i class="fa fa-fill"></i> Fermer</a> {% endif %}{% if perms.gestion.change_keg %}<a href="{% url 'gestion:editKeg' kegH.keg.pk %}" class="button small"><i class="fa fa-pencil-alt"></i> Modifier</a>{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
@ -60,13 +62,13 @@
|
|||
<h2>Liste des fûts inactifs</h2>
|
||||
</header>
|
||||
{% if perms.gestion.add_keg %}
|
||||
<a class="button" href="{% url 'gestion:addKeg' %}">Créer un fût</a>
|
||||
<a class="button" href="{% url 'gestion:addKeg' %}"><i class="fa fa-plus-square"></i> Créer un fût</a>
|
||||
{% endif %}
|
||||
{% if perms.gestion.open_keg %}
|
||||
<a class="button" href="{% url 'gestion:openKeg' %}">Percuter un fût</a>
|
||||
<a class="button" href="{% url 'gestion:openKeg' %}"><i class="fa fa-fill-drip"></i> Percuter un fût</a>
|
||||
{% endif %}
|
||||
{% if perms.gestion.close_keg %}
|
||||
<a class="button" href="{% url 'gestion:closeKeg' %}">Fermer un fût</a>
|
||||
<a class="button" href="{% url 'gestion:closeKeg' %}"><i class="fa fa-fill"></i> Fermer un fût</a>
|
||||
{% endif %}
|
||||
<br><br>
|
||||
<div class="table-wrapper">
|
||||
|
@ -78,6 +80,7 @@
|
|||
<th>Code barre</th>
|
||||
<th>Capacité</th>
|
||||
<th>Prix du fût</th>
|
||||
<th>Degré</th>
|
||||
<th>Historique</th>
|
||||
<th>Administrer</th>
|
||||
</tr>
|
||||
|
@ -90,8 +93,9 @@
|
|||
<td>{{ keg.barcode }}</td>
|
||||
<td>{{ keg.capacity }} L</td>
|
||||
<td>{{ keg.amount }} €</td>
|
||||
<td>{{ keg.pinte.deg }}°</td>
|
||||
<td><a href="{% url 'gestion:kegH' keg.pk %}">Voir</a></td>
|
||||
<td>{% if perms.gestion.open_keg %}{% if keg.stockHold > 0 %}<a href="{% url 'gestion:openDirectKeg' keg.pk %}" class="button small">Percuter</a> {% endif %}{% endif %}{% if perms.gestion.change_keg %}<a href="{% url 'gestion:editKeg' keg.pk %}" class="button small">Modifier</a>{% endif %}</td>
|
||||
<td>{% if perms.gestion.open_keg %}{% if keg.stockHold > 0 %}<a href="{% url 'gestion:openDirectKeg' keg.pk %}" class="button small"><i class="fa fa-fill-drip"></i> Percuter</a> {% endif %}{% endif %}{% if perms.gestion.change_keg %}<a href="{% url 'gestion:editKeg' keg.pk %}" class="button small"><i class="fa fa-pencil-alt"></i> Modifier</a>{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
</header>
|
||||
<div class="row uniform">
|
||||
<div class="12u$">
|
||||
<a class="button small" href="">Annuler</a><br><br>
|
||||
<a class="button small" href=""><i class="fa fa-times"></i> Annuler</a><br><br>
|
||||
{{gestion_form}}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -115,6 +115,19 @@
|
|||
<div class="boutonProduit">
|
||||
<table>
|
||||
<tbody class="actions" id="bouton Produit">
|
||||
<tr class="cotisation-hidden" style="text-align:center; font-weight:bold;"><td colspan="4">Cotisations</td></tr>
|
||||
{% for cotisation in cotisations %}
|
||||
{% if forloop.counter0|divisibleby:4 %}
|
||||
<tr class="cotisation-hidden" style="text-align:center">
|
||||
{% endif %}
|
||||
<td class="cotisation-hidden"><button class="cotisation" target="{{cotisation.pk}}">Cotisation {{cotisation.duration}} jours ({{cotisation.amount}} €)</button></td>
|
||||
{% if forloop.counter|divisibleby:4 %}
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if not bieresPression|divisibleby:4 %}
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr style="text-align:center; font-weight:bold;"><td colspan="4">Bières pression</td></tr>
|
||||
{% for product in bieresPression %}
|
||||
{% if forloop.counter0|divisibleby:4 %}
|
||||
|
@ -214,7 +227,7 @@
|
|||
{% csrf_token %}
|
||||
{{reload_form}}
|
||||
<br>
|
||||
<button type="submit">Recharger</button>
|
||||
<button type="submit"><i class="fa fa-hand-holding-usd"></i> Recharger</button>
|
||||
</form>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
@ -227,7 +240,7 @@
|
|||
{% csrf_token %}
|
||||
{{refund_form}}
|
||||
<br>
|
||||
<button type="submit">Rembourser</button>
|
||||
<button type="submit"><i class="fa fa-file-invoice-dollar"></i> Rembourser</button>
|
||||
</form>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<header class="major">
|
||||
<h2>Liste des menus</h2>
|
||||
</header>
|
||||
<a class="button" href="{% url 'gestion:addMenu' %}">Créer un menu</a><br><br>
|
||||
<a class="button" href="{% url 'gestion:addMenu' %}"><i class="fa fa-plus-square"></i> Créer un menu</a><br><br>
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
|
@ -29,9 +29,9 @@
|
|||
<td>{{ menu.name }}</td>
|
||||
<td>{{ menu.amount}} €</td>
|
||||
<td>{{ menu.barcode }}</td>
|
||||
<td>{% for art in menu.articles.all %}{{art}},{% endfor %}</td>
|
||||
<td>{% for art in menu.articles.all %}<a href="{% url 'gestion:productProfile' art.pk %}">{{art}}</a>,{% endfor %}</td>
|
||||
<td>{{ menu.is_active | yesno:"Oui, Non"}}</td>
|
||||
<td>{% if perms.gestion.change_menu %}<a href="{% url 'gestion:switchActivateMenu' menu.pk %}" class="button small">{% if menu.is_active %}Désa{% else %}A{% endif %}ctiver</a> <a href="{% url 'gestion:editMenu' menu.pk %}" class="button small">Modifier</a>{% endif %}</td>
|
||||
<td>{% if perms.gestion.change_menu %}<a href="{% url 'gestion:switchActivateMenu' menu.pk %}" class="button small">{% if menu.is_active %}<i class="fa fa-times-cirlce"></i> Désa{% else %}<i class="fa fa-check-circle"></i> A{% endif %}ctiver</a> <a href="{% url 'gestion:editMenu' menu.pk %}" class="button small"><i class="fa fa-pencil-alt"></i> Modifier</a>{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<h2>Général</h2>
|
||||
</header>
|
||||
{% if perms.gestion.add_pinte %}
|
||||
<a class="button" href="{% url 'gestion:addPintes' %}">Créer une ou plusieurs pintes</a><br><br>
|
||||
<a class="button" href="{% url 'gestion:addPintes' %}"><i class="fa fa-glass-whiskey"></i> Créer une ou plusieurs pintes</a><br><br>
|
||||
{% endif %}
|
||||
Il a y actuellement {{ taken_pintes.count|add:free_pintes.count }} pintes, parmis lesquelles <strong>{{ free_pintes.count }} sont rendues</strong> et <strong>{{ taken_pintes.count }} ne sont pas rendues</strong>.
|
||||
</section>
|
||||
|
@ -37,10 +37,10 @@
|
|||
{% for pinte in taken_pintes %}
|
||||
<tr>
|
||||
<td>{{ pinte.pk }}</td>
|
||||
<td>{{ pinte.current_owner }}</td>
|
||||
<td>{{ pinte.previous_owner }}</td>
|
||||
<td>{% if pinte.current_owner %}<a href="{% url 'users:profile' pinte.current_owner.pk %}">{{ pinte.current_owner }}</a>{% endif %}</td>
|
||||
<td>{% if pinte.previous_owner %}<a href="{% url 'users:profile' pinte.previous_owner.pk %}">{{ pinte.previous_owner }}</a>{% endif %}</td>
|
||||
<td>{{ pinte.last_update_date }}</td>
|
||||
<td>{% if perms.gestion.change_pinte %} <a href="{% url 'gestion:release' pinte.pk %}" class="button small">Libérer</a>{% endif %}</td>
|
||||
<td>{% if perms.gestion.change_pinte %} <a href="{% url 'gestion:release' pinte.pk %}" class="button small"><i class="fa fa-glass-whiskey"></i> Libérer</a>{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
@ -64,7 +64,7 @@
|
|||
{% for pinte in free_pintes %}
|
||||
<tr>
|
||||
<td>{{ pinte.pk }}</td>
|
||||
<td>{{ pinte.previous_owner }}</td>
|
||||
<td>{% if pinte.previous_owner %}<a href="{% url 'users:profile' pinte.previous_owner.pk %}">{{ pinte.previous_owner }}</a>{% endif %}</td>
|
||||
<td>{{ pinte.last_update_date }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr>
|
||||
<td>{{ user }}</td>
|
||||
<td><a href="{% url 'users:profile' user.pk %}" class="button small">Profil</a></td>
|
||||
<td><a href="{% url 'users:profile' user.pk">{{user}}</a></td>
|
||||
<td><a href="{% url 'users:profile' user.pk %}" class="button small"><i class="fa fa-user"></i> Profil</a></td>
|
||||
<td>{{ user.pintes_owned_currently.count }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<h2>Liste des produits</h2>
|
||||
</header>
|
||||
{% if perms.gestion.add_product %}
|
||||
<a class="button" href="{% url 'gestion:addProduct' %}">Créer un produit</a><br><br>
|
||||
<a class="button" href="{% url 'gestion:addProduct' %}"><i class="fa fa-boxes"></i> Créer un produit</a><br><br>
|
||||
{% endif %}
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
|
@ -32,7 +32,7 @@
|
|||
<tbody>
|
||||
{% for product in products %}
|
||||
<tr>
|
||||
<td>{{ product.name }}</td>
|
||||
<td><a href="{% url 'gestion:productProfile' product.pk %}">{{ product.name }}</a></td>
|
||||
<td>{{ product.amount}}</td>
|
||||
<td>{{ product.stockHold }}</td>
|
||||
<td>{{ product.stockBar }}</td>
|
||||
|
@ -41,7 +41,7 @@
|
|||
<td>{{ product.is_active | yesno:"Oui, Non"}}</td>
|
||||
<td>{{ product.deg }}</td>
|
||||
<td>{{ product.volume }} cl</td>
|
||||
<td><a href="{% url 'gestion:productProfile' product.pk %}" class="button small">Profil</a> {% if perms.gestion.change_product %}<a href="{% url 'gestion:switchActivate' product.pk %}" class="button small">{% if product.is_active %}Désa{% else %}A{% endif %}ctiver</a> <a href="{% url 'gestion:editProduct' product.pk %}" class="button small">Modifier</a>{% endif %}</td>
|
||||
<td><a href="{% url 'gestion:productProfile' product.pk %}" class="button small"><i class="fa fa-eye"></i> Profil</a> {% if perms.gestion.change_product %}<a href="{% url 'gestion:switchActivate' product.pk %}" class="button small">{% if product.is_active %}<i class="fa fa-times-circle"></i> Désa{% else %}<i class="fa fa-check-circle"></i> A{% endif %}ctiver</a> <a href="{% url 'gestion:editProduct' product.pk %}" class="button small"><i class="fa fa-pencil-alt"></i> Modifier</a>{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
{% extends "base.html" %}
|
||||
{%load static %}
|
||||
{%block entete%}Classement{%endblock%}
|
||||
{% block nav %}
|
||||
{% block navbar %}
|
||||
<ul>
|
||||
<li><a href="#first">Meilleurs consommateurs (débit)</a></li>
|
||||
<li><a href="#second">Meilleurs consommateurs (alcool)</a></li>
|
||||
<li><a href="#third">Classement par produit</a></li>
|
||||
</ul>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
|
@ -28,7 +29,7 @@
|
|||
{%for customer in bestBuyers%}
|
||||
<tr>
|
||||
<th>{{ forloop.counter }}</th>
|
||||
<th>{{ customer.username }}</th>
|
||||
<th><a href="{% url 'users:profile' customer.pk %}">{{ customer.username }}</a></th>
|
||||
<th>{{ customer.profile.debit }}€</th>
|
||||
</tr>
|
||||
{%endfor%}
|
||||
|
@ -59,7 +60,7 @@
|
|||
{% for customer in bestDrinkers %}
|
||||
<tr>
|
||||
<th>{{ forloop.counter }}</th>
|
||||
<th>{{ customer.0.username }}</th>
|
||||
<th><a href="{% url 'users:profile' customer.0.pk %}">{{ customer.0.username }}</a></th>
|
||||
<th>{{ customer.1 }}</th>
|
||||
</tr>
|
||||
{%endfor%}
|
||||
|
@ -70,4 +71,44 @@
|
|||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="third" class="main">
|
||||
<div class="spotlight">
|
||||
<div class="content">
|
||||
<header class="major">
|
||||
<h2>Classement par produit</h2>
|
||||
</header>
|
||||
<div class="row">
|
||||
<div class="8u 12u$(medium)">
|
||||
<form action="" method="POST">
|
||||
{% csrf_token %}
|
||||
{{form}}
|
||||
<br><br>
|
||||
<button type="submit" class="button">Afficher</button>
|
||||
</form>
|
||||
{% if product_ranking %}
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Place</th>
|
||||
<th>Pseudo</th>
|
||||
<th>Quantités consommées</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for customer in product_ranking %}
|
||||
<tr>
|
||||
<th>{{ forloop.counter }}</th>
|
||||
<th><a href="{% url 'users:profile' customer.0.pk %}">{{ customer.0.username }}</a></th>
|
||||
<th>{{ customer.1 }}</th>
|
||||
</tr>
|
||||
{%endfor%}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{{form.media}}
|
||||
{%endblock%}
|
121
gestion/views.py
121
gestion/views.py
|
@ -7,19 +7,20 @@ from django.views.decorators.csrf import csrf_exempt
|
|||
from django.contrib.auth.decorators import login_required, permission_required
|
||||
from django.utils import timezone
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.db import transaction
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from django_tex.views import render_to_pdf
|
||||
|
||||
from coopeV3.acl import active_required, acl_or, admin_required
|
||||
|
||||
import simplejson as json
|
||||
from dal import autocomplete
|
||||
from decimal import *
|
||||
import datetime
|
||||
|
||||
from .forms import ReloadForm, RefundForm, ProductForm, KegForm, MenuForm, GestionForm, SearchMenuForm, SearchProductForm, SelectPositiveKegForm, SelectActiveKegForm, PinteForm, GenerateReleveForm
|
||||
from .models import Product, Menu, Keg, ConsumptionHistory, KegHistory, Consumption, MenuHistory, Pinte, Reload, Refund
|
||||
from preferences.models import PaymentMethod, GeneralPreferences
|
||||
from preferences.models import PaymentMethod, GeneralPreferences, Cotisation
|
||||
from users.models import CotisationHistory
|
||||
|
||||
@active_required
|
||||
|
@ -77,6 +78,7 @@ def manage(request):
|
|||
menus = Menu.objects.filter(is_active=True)
|
||||
kegs = Keg.objects.filter(is_active=True)
|
||||
gp, _ = GeneralPreferences.objects.get_or_create(pk=1)
|
||||
cotisations = Cotisation.objects.all()
|
||||
floating_buttons = gp.floating_buttons
|
||||
for keg in kegs:
|
||||
if(keg.pinte):
|
||||
|
@ -97,6 +99,7 @@ def manage(request):
|
|||
"menus": menus,
|
||||
"pay_buttons": pay_buttons,
|
||||
"floating_buttons": floating_buttons,
|
||||
"cotisations": cotisations
|
||||
})
|
||||
|
||||
@csrf_exempt
|
||||
|
@ -107,8 +110,11 @@ def order(request):
|
|||
"""
|
||||
Process the given order. Called by a js/JQuery script.
|
||||
"""
|
||||
error_message = "Impossible d'effectuer la transaction. Toute opération abandonnée. Veuillez contacter le président ou le trésorier"
|
||||
try:
|
||||
with transaction.atomic():
|
||||
if("user" not in request.POST or "paymentMethod" not in request.POST or "amount" not in request.POST or "order" not in request.POST):
|
||||
return HttpResponse("Erreur du POST")
|
||||
raise Exception("Erreur du post")
|
||||
else:
|
||||
user = get_object_or_404(User, pk=request.POST['user'])
|
||||
paymentMethod = get_object_or_404(PaymentMethod, pk=request.POST['paymentMethod'])
|
||||
|
@ -116,9 +122,34 @@ def order(request):
|
|||
order = json.loads(request.POST["order"])
|
||||
menus = json.loads(request.POST["menus"])
|
||||
listPintes = json.loads(request.POST["listPintes"])
|
||||
cotisations = json.loads(request.POST['cotisations'])
|
||||
gp,_ = GeneralPreferences.objects.get_or_create(pk=1)
|
||||
if (not order) and (not menus):
|
||||
return HttpResponse("Pas de commande")
|
||||
if (not order) and (not menus) and (not cotisations):
|
||||
error_message = "Pas de commande"
|
||||
raise Exception(error_message)
|
||||
if(cotisations):
|
||||
for co in cotisations:
|
||||
cotisation = Cotisation.objects.get(pk=co['pk'])
|
||||
for i in range(co['quantity']):
|
||||
cotisation_history = CotisationHistory(cotisation=cotisation)
|
||||
if(paymentMethod.affect_balance):
|
||||
if(user.profile.balance >= cotisation_history.cotisation.amount):
|
||||
user.profile.debit += cotisation_history.cotisation.amount
|
||||
else:
|
||||
error_message = "Solde insuffisant"
|
||||
raise Exception(error_message)
|
||||
cotisation_history.user = user
|
||||
cotisation_history.coopeman = request.user
|
||||
cotisation_history.amount = cotisation.amount
|
||||
cotisation_history.duration = cotisation.duration
|
||||
cotisation_history.paymentMethod = paymentMethod
|
||||
if(user.profile.cotisationEnd and user.profile.cotisationEnd > timezone.now()):
|
||||
cotisation_history.endDate = user.profile.cotisationEnd + timedelta(days=cotisation.duration)
|
||||
else:
|
||||
cotisation_history.endDate = timezone.now() + timedelta(days=cotisation.duration)
|
||||
user.profile.cotisationEnd = cotisation_history.endDate
|
||||
user.save()
|
||||
cotisation_history.save()
|
||||
adherentRequired = False
|
||||
for o in order:
|
||||
product = get_object_or_404(Product, pk=o["pk"])
|
||||
|
@ -127,18 +158,21 @@ def order(request):
|
|||
menu = get_object_or_404(Menu, pk=m["pk"])
|
||||
adherentRequired = adherentRequired or menu.adherent_required
|
||||
if(adherentRequired and not user.profile.is_adherent):
|
||||
return HttpResponse("N'est pas adhérent et devrait l'être")
|
||||
error_message = "N'est pas adhérent et devrait l'être."
|
||||
raise Exception(error_message)
|
||||
# Partie un peu complexe : je libère toutes les pintes de la commande, puis je test
|
||||
# s'il a trop de pintes non rendues, puis je réalloue les pintes
|
||||
for pinte in listPintes:
|
||||
allocate(pinte, None)
|
||||
if(gp.lost_pintes_allowed and user.profile.nb_pintes >= gp.lost_pintes_allowed):
|
||||
return HttpResponse("Impossible de réaliser la commande : l'utilisateur a perdu trop de pintes.")
|
||||
if(gp.use_pinte_monitoring and gp.lost_pintes_allowed and user.profile.nb_pintes >= gp.lost_pintes_allowed):
|
||||
error_message = "Impossible de réaliser la commande : l'utilisateur a perdu trop de pintes."
|
||||
raise Exception(error_message)
|
||||
for pinte in listPintes:
|
||||
allocate(pinte, user)
|
||||
if(paymentMethod.affect_balance):
|
||||
if(user.profile.balance < amount):
|
||||
return HttpResponse("Solde inférieur au prix de la commande")
|
||||
error_message = "Solde inférieur au prix de la commande"
|
||||
raise Exception(error_message)
|
||||
else:
|
||||
user.profile.debit += amount
|
||||
user.save()
|
||||
|
@ -148,7 +182,7 @@ def order(request):
|
|||
if(product.category == Product.P_PRESSION):
|
||||
keg = get_object_or_404(Keg, pinte=product)
|
||||
if(not keg.is_active):
|
||||
return HttpResponse("Une erreur inconnue s'est produite. Veuillez contacter le trésorier ou le président")
|
||||
raise Exception("Fût non actif")
|
||||
kegHistory = get_object_or_404(KegHistory, keg=keg, isCurrentKegHistory=True)
|
||||
kegHistory.quantitySold += Decimal(quantity * 0.5)
|
||||
kegHistory.amountSold += Decimal(quantity * product.amount)
|
||||
|
@ -156,7 +190,7 @@ def order(request):
|
|||
elif(product.category == Product.D_PRESSION):
|
||||
keg = get_object_or_404(Keg, demi=product)
|
||||
if(not keg.is_active):
|
||||
return HttpResponse("Une erreur inconnue s'est produite. Veuillez contacter le trésorier ou le président")
|
||||
raise Exception("Fût non actif")
|
||||
kegHistory = get_object_or_404(KegHistory, keg=keg, isCurrentKegHistory=True)
|
||||
kegHistory.quantitySold += Decimal(quantity * 0.25)
|
||||
kegHistory.amountSold += Decimal(quantity * product.amount)
|
||||
|
@ -164,7 +198,7 @@ def order(request):
|
|||
elif(product.category == Product.G_PRESSION):
|
||||
keg = get_object_or_404(Keg, galopin=product)
|
||||
if(not keg.is_active):
|
||||
return HttpResponse("Une erreur inconnue s'est produite. Veuillez contacter le trésorier ou le président")
|
||||
raise Exception("Fût non actif")
|
||||
kegHistory = get_object_or_404(KegHistory, keg=keg, isCurrentKegHistory=True)
|
||||
kegHistory.quantitySold += Decimal(quantity * 0.125)
|
||||
kegHistory.amountSold += Decimal(quantity * product.amount)
|
||||
|
@ -178,11 +212,21 @@ def order(request):
|
|||
consumption.save()
|
||||
ch = ConsumptionHistory(customer=user, quantity=quantity, paymentMethod=paymentMethod, product=product, amount=Decimal(quantity*product.amount), coopeman=request.user)
|
||||
ch.save()
|
||||
if(user.profile.balance > Decimal(product.amount * quantity)):
|
||||
user.profile.debit += Decimal(product.amount*quantity)
|
||||
else:
|
||||
error_message = "Solde insuffisant"
|
||||
raise Exception(error_message)
|
||||
for m in menus:
|
||||
menu = get_object_or_404(Menu, pk=m["pk"])
|
||||
quantity = int(m["quantity"])
|
||||
mh = MenuHistory(customer=user, quantity=quantity, paymentMethod=paymentMethod, menu=menu, amount=int(quantity*menu.amount), coopeman=request.user)
|
||||
mh.save()
|
||||
if(user.profile.balance > Decimal(menu.amount * quantity)):
|
||||
user.profile.debit += Decimal(menu.amount*quantity)
|
||||
else:
|
||||
error_message = "Solde insuffisant"
|
||||
raise Exception(error_message)
|
||||
for article in menu.articles.all():
|
||||
consumption, _ = Consumption.objects.get_or_create(customer=user, product=article)
|
||||
consumption.quantity += quantity
|
||||
|
@ -191,6 +235,10 @@ def order(request):
|
|||
article.stockHold -= 1
|
||||
article.save()
|
||||
return HttpResponse("La commande a bien été effectuée")
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print("test")
|
||||
return HttpResponse(error_message)
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -341,7 +389,7 @@ def addProduct(request):
|
|||
product = form.save()
|
||||
messages.success(request, "Le produit a bien été ajouté")
|
||||
return redirect(reverse('gestion:productProfile', kwargs={'pk':product.pk}))
|
||||
return render(request, "form.html", {"form": form, "form_title": "Ajout d'un produit", "form_button": "Ajouter"})
|
||||
return render(request, "form.html", {"form": form, "form_title": "Ajout d'un produit", "form_button": "Ajouter", "form_button_icon": "plus-square"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -374,7 +422,7 @@ def editProduct(request, pk):
|
|||
form.save()
|
||||
messages.success(request, "Le produit a bien été modifié")
|
||||
return redirect(reverse('gestion:productProfile', kwargs={'pk':product.pk}))
|
||||
return render(request, "form.html", {"form": form, "form_title": "Modification d'un produit", "form_button": "Modifier"})
|
||||
return render(request, "form.html", {"form": form, "form_title": "Modification d'un produit", "form_button": "Modifier", "form_button_icon": "pencil-alt"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -420,7 +468,7 @@ def searchProduct(request):
|
|||
form = SearchProductForm(request.POST or None)
|
||||
if(form.is_valid()):
|
||||
return redirect(reverse('gestion:productProfile', kwargs={'pk': form.cleaned_data['product'].pk }))
|
||||
return render(request, "form.html", {"form": form, "form_title":"Rechercher un produit", "form_button": "Rechercher"})
|
||||
return render(request, "form.html", {"form": form, "form_title":"Rechercher un produit", "form_button": "Rechercher", "form_button_icon": "search"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -484,7 +532,7 @@ class ProductsAutocomplete(autocomplete.Select2QuerySetView):
|
|||
def get_queryset(self):
|
||||
qs = Product.objects.all()
|
||||
if self.q:
|
||||
qs = qs.filter(name__istartswith=self.q)
|
||||
qs = qs.filter(name__contains=self.q)
|
||||
return qs
|
||||
|
||||
class ActiveProductsAutocomplete(autocomplete.Select2QuerySetView):
|
||||
|
@ -494,7 +542,7 @@ class ActiveProductsAutocomplete(autocomplete.Select2QuerySetView):
|
|||
def get_queryset(self):
|
||||
qs = Product.objects.filter(is_active=True)
|
||||
if self.q:
|
||||
qs = qs.filter(name__istartswith=self.q)
|
||||
qs = qs.filter(name__contains=self.q)
|
||||
return qs
|
||||
|
||||
########## Kegs ##########
|
||||
|
@ -526,7 +574,7 @@ def addKeg(request):
|
|||
keg = form.save()
|
||||
messages.success(request, "Le fût " + keg.name + " a bien été ajouté")
|
||||
return redirect(reverse('gestion:kegsList'))
|
||||
return render(request, "form.html", {"form":form, "form_title": "Ajout d'un fût", "form_button": "Ajouter"})
|
||||
return render(request, "form.html", {"form":form, "form_title": "Ajout d'un fût", "form_button": "Ajouter", "form_button_icon": "plus-square"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -559,7 +607,7 @@ def editKeg(request, pk):
|
|||
form.save()
|
||||
messages.success(request, "Le fût a bien été modifié")
|
||||
return redirect(reverse('gestion:kegsList'))
|
||||
return render(request, "form.html", {"form": form, "form_title": "Modification d'un fût", "form_button": "Modifier"})
|
||||
return render(request, "form.html", {"form": form, "form_title": "Modification d'un fût", "form_button": "Modifier", "form_button_icon": "pencil-alt"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -598,7 +646,7 @@ def openKeg(request):
|
|||
keg.save()
|
||||
messages.success(request, "Le fut a bien été percuté")
|
||||
return redirect(reverse('gestion:kegsList'))
|
||||
return render(request, "form.html", {"form": form, "form_title":"Percutage d'un fût", "form_button":"Percuter"})
|
||||
return render(request, "form.html", {"form": form, "form_title":"Percutage d'un fût", "form_button":"Percuter", "form_button_icon": "fill-drip"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -660,7 +708,7 @@ def closeKeg(request):
|
|||
keg.save()
|
||||
messages.success(request, "Le fût a bien été fermé")
|
||||
return redirect(reverse('gestion:kegsList'))
|
||||
return render(request, "form.html", {"form": form, "form_title":"Fermeture d'un fût", "form_button":"Fermer le fût"})
|
||||
return render(request, "form.html", {"form": form, "form_title":"Fermeture d'un fût", "form_button":"Fermer le fût", "form_button_icon": "fill"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -742,7 +790,7 @@ class KegActiveAutocomplete(autocomplete.Select2QuerySetView):
|
|||
def get_queryset(self):
|
||||
qs = Keg.objects.filter(is_active = True)
|
||||
if self.q:
|
||||
qs = qs.filter(name__istartswith=self.q)
|
||||
qs = qs.filter(name__contains=self.q)
|
||||
return qs
|
||||
|
||||
class KegPositiveAutocomplete(autocomplete.Select2QuerySetView):
|
||||
|
@ -752,7 +800,7 @@ class KegPositiveAutocomplete(autocomplete.Select2QuerySetView):
|
|||
def get_queryset(self):
|
||||
qs = Keg.objects.filter(stockHold__gt = 0)
|
||||
if self.q:
|
||||
qs = qs.filter(name__istartswith=self.q)
|
||||
qs = qs.filter(name__contains=self.q)
|
||||
return qs
|
||||
|
||||
########## Menus ##########
|
||||
|
@ -785,7 +833,7 @@ def addMenu(request):
|
|||
menu = form.save()
|
||||
messages.success(request, "Le menu " + menu.name + " a bien été ajouté")
|
||||
return redirect(reverse('gestion:menusList'))
|
||||
return render(request, "form.html", {"form":form, "form_title": "Ajout d'un menu", "form_button": "Ajouter", "extra_css": extra_css})
|
||||
return render(request, "form.html", {"form":form, "form_title": "Ajout d'un menu", "form_button": "Ajouter", "form_button_icon": "plus-square", "extra_css": extra_css})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -819,7 +867,7 @@ def edit_menu(request, pk):
|
|||
form.save()
|
||||
messages.success(request, "Le menu a bien été modifié")
|
||||
return redirect(reverse('gestion:menusList'))
|
||||
return render(request, "form.html", {"form": form, "form_title": "Modification d'un menu", "form_button": "Modifier", "extra_css": extra_css})
|
||||
return render(request, "form.html", {"form": form, "form_title": "Modification d'un menu", "form_button": "Modifier", "form_button_icon": "pencil-alt", "extra_css": extra_css})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -847,7 +895,7 @@ def searchMenu(request):
|
|||
if(form.is_valid()):
|
||||
menu = form.cleaned_data['menu']
|
||||
return redirect(reverse('gestion:editMenu', kwargs={'pk':menu.pk}))
|
||||
return render(request, "form.html", {"form": form, "form_title": "Recherche d'un menu", "form_button": "Modifier"})
|
||||
return render(request, "form.html", {"form": form, "form_title": "Recherche d'un menu", "form_button": "Modifier", "form_button_icon": "search"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -899,7 +947,7 @@ def get_menu(request, pk):
|
|||
for article in menu.articles:
|
||||
if article.category == Product.P_PRESSION:
|
||||
nb_pintes +=1
|
||||
data = json.dumps({"pk": menu.pk, "barcode" : menu.barcode, "name": menu.name, "amount" : menu.amount, needQuantityButton: False, "nb_pintes": nb_pintes})
|
||||
data = json.dumps({"pk": menu.pk, "barcode" : menu.barcode, "name": menu.name, "amount" : menu.amount, "needQuantityButton": False, "nb_pintes": nb_pintes})
|
||||
return HttpResponse(data, content_type='application/json')
|
||||
|
||||
class MenusAutocomplete(autocomplete.Select2QuerySetView):
|
||||
|
@ -909,7 +957,7 @@ class MenusAutocomplete(autocomplete.Select2QuerySetView):
|
|||
def get_queryset(self):
|
||||
qs = Menu.objects.all()
|
||||
if self.q:
|
||||
qs = qs.filter(name__istartswith=self.q)
|
||||
qs = qs.filter(name__contains=self.q)
|
||||
return qs
|
||||
|
||||
########## Ranking ##########
|
||||
|
@ -939,7 +987,12 @@ def ranking(request):
|
|||
alcohol = customer.profile.alcohol
|
||||
list.append([customer, alcohol])
|
||||
bestDrinkers = sorted(list, key=lambda x: x[1], reverse=True)[:25]
|
||||
return render(request, "gestion/ranking.html", {"bestBuyers": bestBuyers, "bestDrinkers": bestDrinkers})
|
||||
form = SearchProductForm(request.POST or None)
|
||||
if(form.is_valid()):
|
||||
product_ranking = form.cleaned_data['product'].ranking
|
||||
else:
|
||||
product_ranking = None
|
||||
return render(request, "gestion/ranking.html", {"bestBuyers": bestBuyers, "bestDrinkers": bestDrinkers, "product_ranking": product_ranking, "form": form})
|
||||
|
||||
########## Pinte monitoring ##########
|
||||
|
||||
|
@ -989,7 +1042,7 @@ def add_pintes(request):
|
|||
i += 1
|
||||
messages.success(request, str(i) + " pinte(s) a(ont) été ajoutée(s)")
|
||||
return redirect(reverse('gestion:productsIndex'))
|
||||
return render(request, "form.html", {"form": form, "form_title": "Ajouter des pintes", "form_button": "Ajouter"})
|
||||
return render(request, "form.html", {"form": form, "form_title": "Ajouter des pintes", "form_button": "Ajouter", "form_button_icon": "plus-square"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -1008,7 +1061,7 @@ def release_pintes(request):
|
|||
i += 1
|
||||
messages.success(request, str(i) + " pinte(s) a(ont) été libérée(s)")
|
||||
return redirect(reverse('gestion:productsIndex'))
|
||||
return render(request, "form.html", {"form": form, "form_title": "Libérer des pintes", "form_button": "Libérer"})
|
||||
return render(request, "form.html", {"form": form, "form_title": "Libérer des pintes", "form_button": "Libérer", "form_button_icon": "glass-whiskey"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -1069,7 +1122,7 @@ def gen_releve(request):
|
|||
value_lydia += cot.amount
|
||||
elif pm == cheque:
|
||||
value_cheque += cot.amount
|
||||
now = datetime.datetime.now()
|
||||
now = datetime.now()
|
||||
return render_to_pdf(request, 'gestion/releve.tex', {"consumptions": consumptions, "reloads": reloads, "refunds": refunds, "cotisations": cotisations, "begin": begin, "end": end, "now": now, "value_especes": value_especes, "value_lydia": value_lydia, "value_cheque": value_cheque}, filename="releve.pdf")
|
||||
else:
|
||||
return render(request, "form.html", {"form": form, "form_title": "Génération d'un relevé", "form_button": "Générer"})
|
||||
return render(request, "form.html", {"form": form, "form_title": "Génération d'un relevé", "form_button": "Générer", "form_button_icon": "file-pdf"})
|
||||
|
|
|
@ -36,5 +36,6 @@ class GeneralPreferencesForm(forms.ModelForm):
|
|||
'treasurer': forms.TextInput(attrs={'placeholder': 'Trésorier'}),
|
||||
'brewer': forms.TextInput(attrs={'placeholder': 'Maître brasseur'}),
|
||||
'grocer': forms.TextInput(attrs={'placeholder': 'Epic épicier'}),
|
||||
'home_text': forms.Textarea(attrs={'placeholder': 'Ce message sera affiché sur la page d\'accueil'})
|
||||
}
|
||||
|
||||
|
|
23
preferences/migrations/0006_auto_20190119_2326.py
Normal file
23
preferences/migrations/0006_auto_20190119_2326.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Generated by Django 2.1 on 2019-01-19 22:26
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('preferences', '0005_auto_20190106_0513'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='generalpreferences',
|
||||
name='home_text',
|
||||
field=models.TextField(blank=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='historicalgeneralpreferences',
|
||||
name='home_text',
|
||||
field=models.TextField(blank=True),
|
||||
),
|
||||
]
|
23
preferences/migrations/0007_auto_20190120_1208.py
Normal file
23
preferences/migrations/0007_auto_20190120_1208.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Generated by Django 2.1 on 2019-01-20 11:08
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('preferences', '0006_auto_20190119_2326'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='generalpreferences',
|
||||
name='automatic_logout_time',
|
||||
field=models.PositiveIntegerField(null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='historicalgeneralpreferences',
|
||||
name='automatic_logout_time',
|
||||
field=models.PositiveIntegerField(null=True),
|
||||
),
|
||||
]
|
|
@ -34,6 +34,8 @@ class GeneralPreferences(models.Model):
|
|||
use_pinte_monitoring = models.BooleanField(default=False)
|
||||
lost_pintes_allowed = models.PositiveIntegerField(default=0)
|
||||
floating_buttons = models.BooleanField(default=False)
|
||||
home_text = models.TextField(blank=True)
|
||||
automatic_logout_time = models.PositiveIntegerField(null=True)
|
||||
history = HistoricalRecords()
|
||||
|
||||
class Cotisation(models.Model):
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<h2>Liste des cotisations</h2>
|
||||
</header>
|
||||
{% if perms.preferences.add_cotisation %}
|
||||
<a class="button" href="{% url 'preferences:addCotisation' %}">Créer une cotisation</a><br><br>
|
||||
<a class="button" href="{% url 'preferences:addCotisation' %}"><i class="fa fa-plus-square"></i> Créer une cotisation</a><br><br>
|
||||
{% endif %}
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
|
@ -27,7 +27,7 @@
|
|||
<tr>
|
||||
<td>{{ cotisation.duration }} jours</td>
|
||||
<td>{{ cotisation.amount }} €</td>
|
||||
<td>{% if perms.preferences.change_cotisation %}<a class="button small" href="{% url 'preferences:editCotisation' cotisation.pk %}">Modifier</a> {% endif %}{% if perms.preferences.delete_cotisation %}<a class="button small" href="{% url 'preferences:deleteCotisation' cotisation.pk %}">Supprimer</a>{% endif %}</td>
|
||||
<td>{% if perms.preferences.change_cotisation %}<a class="button small" href="{% url 'preferences:editCotisation' cotisation.pk %}"><i class="fa fa-pencil-alt"></i> Modifier</a> {% endif %}{% if perms.preferences.delete_cotisation %}<a class="button small" href="{% url 'preferences:deleteCotisation' cotisation.pk %}"><i class="fa fa-trash"></i> Supprimer</a>{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
</div>
|
||||
<div class="row uniform">
|
||||
<div class="12u">
|
||||
<button type="submit">Enregistrer</button>
|
||||
<button type="submit"><i class="fa fa-save"></i> Enregistrer</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -51,7 +51,7 @@
|
|||
</div>
|
||||
<div class="row uniform">
|
||||
<div class="12u">
|
||||
<button type="submit">Enregistrer</button>
|
||||
<button type="submit"><i class="fa fa-save"></i> Enregistrer</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -89,7 +89,7 @@
|
|||
</div>
|
||||
<div class="row uniform">
|
||||
<div class="12u">
|
||||
<button type="submit">Enregistrer</button>
|
||||
<button type="submit"><i class="fa fa-save"></i> Enregistrer</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -115,7 +115,7 @@
|
|||
</div>
|
||||
<div class="row uniform">
|
||||
<div class="12u">
|
||||
<button type="submit">Enregistrer</button>
|
||||
<button type="submit"><i class="fa fa-save"></i> Enregistrer</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -127,15 +127,32 @@
|
|||
<header class="major">
|
||||
<h2>Autre</h2>
|
||||
</header>
|
||||
<br>
|
||||
<h3>Boutons flottants</h3>
|
||||
<div class="row uniform">
|
||||
<div class="12u">
|
||||
{{form.floating_buttons}}
|
||||
<label for="{{form.floating_buttons.id_for_label}}">Utiliser les boutons de paiement flottants ?</label>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<h3>Déconnexion automatique</h3>
|
||||
<div class="row uniform">
|
||||
<div class="12u">
|
||||
<button type="submit">Enregistrer</button>
|
||||
{{form.automatic_logout_time}}
|
||||
<label for="{{form.automatic_logout_time.id_for_label}}">Temps (en minutes) au bout duquel l'utilisateur est déconnecté automatiquement (0 pour qu'il reste connecté)</label>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<h3>Texte de la page d'accueil</h3>
|
||||
<div class="row uniform">
|
||||
<div class="12u">
|
||||
{{form.home_text}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row uniform">
|
||||
<div class="12u">
|
||||
<button type="submit"><i class="fa fa-save"></i> Enregistrer</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<h2>Liste des moyens de paiement</h2>
|
||||
</header>
|
||||
{% if perms.preferences.add_paymentmethod %}
|
||||
<a class="button" href="{% url 'preferences:addPaymentMethod' %}">Créer un moyen de paiement</a><br><br>
|
||||
<a class="button" href="{% url 'preferences:addPaymentMethod' %}"><i class="fa fa-plus-square"></i> Créer un moyen de paiement</a><br><br>
|
||||
{% endif %}
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
|
@ -35,7 +35,7 @@
|
|||
<td>{{ pm.is_usable_in_reload | yesno:"Oui, Non" }}</td>
|
||||
<td>{{ pm.affect_balance | yesno:"Oui, Non" }}</td>
|
||||
<td><i class="fa fa-{{ pm.icon }}"></i></td>
|
||||
<td>{% if perms.preferences.change_paymentmethod %}<a class="button small" href="{% url 'preferences:editPaymentMethod' pm.pk %}">Modifier</a> {% endif %}{% if perms.preferences.delete_paymentmethod %}<a class="button small" href="{% url 'preferences:deletePaymentMethod' pm.pk %}">Supprimer</a>{% endif %}</td>
|
||||
<td>{% if perms.preferences.change_paymentmethod %}<a class="button small" href="{% url 'preferences:editPaymentMethod' pm.pk %}"><i class="fa fa-pencil-alt"></i> Modifier</a> {% endif %}{% if perms.preferences.delete_paymentmethod %}<a class="button small" href="{% url 'preferences:deletePaymentMethod' pm.pk %}"><i class="fa fa-trash"></i> Supprimer</a>{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
|
@ -15,4 +15,5 @@ urlpatterns = [
|
|||
path('deletePaymentMethod/<int:pk>', views.deletePaymentMethod, name="deletePaymentMethod"),
|
||||
path('inactive', views.inactive, name="inactive"),
|
||||
path('getConfig', views.get_config, name="getConfig"),
|
||||
]
|
||||
path('getCotisation/<int:pk>', views.get_cotisation, name="getCotisation")
|
||||
,]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import json
|
||||
import simplejson as json
|
||||
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.contrib import messages
|
||||
|
@ -84,7 +84,7 @@ def addCotisation(request):
|
|||
cotisation = form.save()
|
||||
messages.success(request, "La cotisation (" + str(cotisation.duration) + " jours, " + str(cotisation.amount) + "€) a bien été créée")
|
||||
return redirect(reverse('preferences:cotisationsIndex'))
|
||||
return render(request, "form.html", {"form": form, "form_title": "Création d'une cotisation", "form_button": "Créer"})
|
||||
return render(request, "form.html", {"form": form, "form_title": "Création d'une cotisation", "form_button": "Créer", "form_button_icon": "plus-square"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -117,7 +117,7 @@ def editCotisation(request, pk):
|
|||
cotisation = form.save()
|
||||
messages.success(request, "La cotisation (" + str(cotisation.duration) + " jours, " + str(cotisation.amount) + "€) a bien été modifiée")
|
||||
return redirect(reverse('preferences:cotisationsIndex'))
|
||||
return render(request, "form.html", {"form": form, "form_title": "Modification d'une cotisation", "form_button": "Modifier"})
|
||||
return render(request, "form.html", {"form": form, "form_title": "Modification d'une cotisation", "form_button": "Modifier", "form_button_icon": "pencil-alt"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -135,6 +135,19 @@ def deleteCotisation(request,pk):
|
|||
messages.success(request, message)
|
||||
return redirect(reverse('preferences:cotisationsIndex'))
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
@permission_required('preferences.view_cotisation')
|
||||
def get_cotisation(request, pk):
|
||||
"""
|
||||
Get a cotisation by pk
|
||||
|
||||
``pk``
|
||||
The primary key of the cotisation
|
||||
"""
|
||||
cotisation = get_object_or_404(Cotisation, pk=pk)
|
||||
data = json.dumps({"pk": cotisation.pk, "duration": cotisation.duration, "amount" : cotisation.amount, "needQuantityButton": False})
|
||||
return HttpResponse(data, content_type='application/json')
|
||||
|
||||
########## Payment Methods ##########
|
||||
|
||||
|
@ -184,7 +197,7 @@ def addPaymentMethod(request):
|
|||
paymentMethod = form.save()
|
||||
messages.success(request, "Le moyen de paiement " + paymentMethod.name + " a bien été crée")
|
||||
return redirect(reverse('preferences:paymentMethodsIndex'))
|
||||
return render(request, "form.html", {"form": form, "form_title": "Création d'un moyen de paiement", "form_button": "Créer"})
|
||||
return render(request, "form.html", {"form": form, "form_title": "Création d'un moyen de paiement", "form_button": "Créer", "form_button_icon": "plus-square"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -217,7 +230,7 @@ def editPaymentMethod(request, pk):
|
|||
paymentMethod = form.save()
|
||||
messages.success(request, "Le moyen de paiment " + paymentMethod.name + " a bien été modifié")
|
||||
return redirect(reverse('preferences:paymentMethodsIndex'))
|
||||
return render(request, "form.html", {"form": form, "form_title": "Modification d'un moyen de paiement", "form_button": "Modifier"})
|
||||
return render(request, "form.html", {"form": form, "form_title": "Modification d'un moyen de paiement", "form_button": "Modifier", "form_button_icon": "pencil-alt"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
|
136
staticfiles/css/runner.css
Normal file
136
staticfiles/css/runner.css
Normal file
|
@ -0,0 +1,136 @@
|
|||
/* Copyright 2013 The Chromium Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file. */
|
||||
|
||||
html, body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.icon {
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.icon-offline {
|
||||
content: -webkit-image-set( url(../runner-assets/default_100_percent/100-error-offline.png) 1x, url(../runner-assets/default_200_percent/200-error-offline.png) 2x);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/* Offline page */
|
||||
|
||||
.offline .interstitial-wrapper {
|
||||
color: #2b2b2b;
|
||||
font-size: 1em;
|
||||
line-height: 1.55;
|
||||
margin: 0 auto;
|
||||
max-width: 600px;
|
||||
padding-top: 100px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.offline .runner-container {
|
||||
height: 150px;
|
||||
max-width: 600px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 35px;
|
||||
width: 44px;
|
||||
}
|
||||
|
||||
.offline .runner-canvas {
|
||||
height: 150px;
|
||||
max-width: 600px;
|
||||
opacity: 1;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.offline .controller {
|
||||
background: rgba(247, 247, 247, .1);
|
||||
height: 100vh;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100vw;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#offline-resources {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (max-width: 420px) {
|
||||
.suggested-left > #control-buttons, .suggested-right > #control-buttons {
|
||||
float: none;
|
||||
}
|
||||
.snackbar {
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-height: 350px) {
|
||||
h1 {
|
||||
margin: 0 0 15px;
|
||||
}
|
||||
.icon-offline {
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
.interstitial-wrapper {
|
||||
margin-top: 5%;
|
||||
}
|
||||
.nav-wrapper {
|
||||
margin-top: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 600px) and (max-width: 736px) and (orientation: landscape) {
|
||||
.offline .interstitial-wrapper {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 420px) and (max-width: 736px) and (min-height: 240px) and (max-height: 420px) and (orientation:landscape) {
|
||||
.interstitial-wrapper {
|
||||
margin-bottom: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-height: 240px) and (orientation: landscape) {
|
||||
.offline .interstitial-wrapper {
|
||||
margin-bottom: 90px;
|
||||
}
|
||||
.icon-offline {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-height: 320px) and (orientation: landscape) {
|
||||
.icon-offline {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.offline .runner-container {
|
||||
top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 240px) {
|
||||
.interstitial-wrapper {
|
||||
overflow: inherit;
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
total = 0
|
||||
products = []
|
||||
menus = []
|
||||
cotisations = []
|
||||
paymentMethod = null
|
||||
balance = 0
|
||||
username = ""
|
||||
id = 0
|
||||
id_user = 0
|
||||
listPintes = []
|
||||
nbPintes = 0;
|
||||
use_pinte_monitoring = false;
|
||||
|
@ -29,9 +30,15 @@ function get_menu(id){
|
|||
});
|
||||
}
|
||||
|
||||
function get_cotisation(id){
|
||||
res = $.get("../preferences/getCotisation/" + id, function(data){
|
||||
add_cotisation(data.pk, "", data.duration, data.amount, data.needQuantityButton);
|
||||
});
|
||||
}
|
||||
|
||||
function add_product(pk, barcode, name, amount, needQuantityButton){
|
||||
exist = false
|
||||
index = -1
|
||||
index = -1;
|
||||
for(k=0;k < products.length; k++){
|
||||
if(products[k].pk == pk){
|
||||
exist = true
|
||||
|
@ -71,15 +78,36 @@ function add_menu(pk, barcode, name, amount){
|
|||
generate_html();
|
||||
}
|
||||
|
||||
function add_cotisation(pk, barcode, duration, amount){
|
||||
exist = false;
|
||||
index = -1;
|
||||
for(k=0; k < cotisations.length; k++){
|
||||
if(cotisations[k].pk == pk){
|
||||
exist = true;
|
||||
index = k;
|
||||
}
|
||||
}
|
||||
if(exist){
|
||||
cotisations[index].quantity += 1;
|
||||
}else{
|
||||
cotisations.push({"pk": pk, "barcode": barcode, "duration": duration, "amount": amount, "quantity":1});
|
||||
}
|
||||
generate_html();
|
||||
}
|
||||
|
||||
function generate_html(){
|
||||
html = "";
|
||||
for(k=0;k<cotisations.length;k++){
|
||||
cotisation = cotisations[k];
|
||||
html += '<tr><td></td><td>Cotisation ' + String(cotisation.duration) + ' jours</td><td>' + String(cotisation.amount) + ' €</td><td><input type="number" data-target="' + String(k) + '" onChange="updateCotisationInput(this)" value="' + String(cotisation.quantity) + '"/></td><td>' + String(Number((cotisation.quantity * cotisation.amount).toFixed(2))) + ' €</td></tr>';
|
||||
}
|
||||
for(k=0;k<products.length;k++){
|
||||
product = products[k]
|
||||
html += '<tr><td>' + product.barcode + '</td><td>' + product.name + '</td><td>' + String(product.amount) + '</td><td><input type="number" data-target="' + String(k) + '" onChange="updateInput(this)" value="' + String(product.quantity) + '"/></td><td>' + String(Number((product.quantity * product.amount).toFixed(2))) + '</td></tr>';
|
||||
html += '<tr><td>' + product.barcode + '</td><td>' + product.name + '</td><td>' + String(product.amount) + ' €</td><td><input type="number" data-target="' + String(k) + '" onChange="updateInput(this)" value="' + String(product.quantity) + '"/></td><td>' + String(Number((product.quantity * product.amount).toFixed(2))) + ' €</td></tr>';
|
||||
}
|
||||
for(k=0; k<menus.length;k++){
|
||||
menu = menus[k]
|
||||
html += '<tr><td>' + menu.barcode + '</td><td>' + menu.name + '</td><td>' + String(menu.amount) + '</td><td><input type="number" data-target="' + String(k) + '" onChange="updateMenuInput(this)" value="' + String(menu.quantity) + '"/></td><td>' + String(Number((menu.quantity * menu.amount).toFixed(2))) + '</td></tr>';
|
||||
html += '<tr><td>' + menu.barcode + '</td><td>' + menu.name + '</td><td>' + String(menu.amount) + ' €</td><td><input type="number" data-target="' + String(k) + '" onChange="updateMenuInput(this)" value="' + String(menu.quantity) + '"/></td><td>' + String(Number((menu.quantity * menu.amount).toFixed(2))) + ' €</td></tr>';
|
||||
}
|
||||
$("#items").html(html)
|
||||
updateTotal();
|
||||
|
@ -93,6 +121,9 @@ function updateTotal(){
|
|||
for(k=0; k<menus.length;k++){
|
||||
total += menus[k].quantity * menus[k].amount;
|
||||
}
|
||||
for(k=0; k<cotisations.length;k++){
|
||||
total += cotisations[k].quantity * cotisations[k].amount;
|
||||
}
|
||||
$("#totalAmount").text(String(Number(total.toFixed(2))) + "€")
|
||||
totalAfter = balance - total
|
||||
$("#totalAfter").text(String(Number(totalAfter.toFixed(2))) + "€")
|
||||
|
@ -112,7 +143,15 @@ function updateMenuInput(a){
|
|||
generate_html();
|
||||
}
|
||||
|
||||
function updateCotisationInput(a){
|
||||
quantity = parseInt(a.value);
|
||||
k = parseInt(a.getAttribute("data-target"));
|
||||
cotisations[k].quantity = quantity;
|
||||
generate_html();
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$(".cotisation-hidden").hide();
|
||||
get_config();
|
||||
|
||||
$(".product").click(function(){
|
||||
|
@ -123,12 +162,20 @@ $(document).ready(function(){
|
|||
menu = get_menu($(this).attr('target'));
|
||||
});
|
||||
|
||||
$(".cotisation").click(function(){
|
||||
cotisation = get_cotisation($(this).attr('target'));
|
||||
});
|
||||
|
||||
$("#id_client").on('change', function(){
|
||||
id = $("#id_client").val();
|
||||
$.get("/users/getUser/" + id, function(data){
|
||||
id_user = $("#id_client").val();
|
||||
$.get("/users/getUser/" + id_user, function(data){
|
||||
balance = data.balance;
|
||||
username = data.username;
|
||||
is_adherent = data.is_adherent;
|
||||
$("#balance").html(balance + "€");
|
||||
if(!is_adherent){
|
||||
$(".cotisation-hidden").show();
|
||||
}
|
||||
updateTotal();
|
||||
}).fail(function(){
|
||||
alert("Une erreur inconnue est survenue");
|
||||
|
@ -159,7 +206,7 @@ $(document).ready(function(){
|
|||
}
|
||||
}
|
||||
}
|
||||
$.post("order", {"user":id, "paymentMethod": $(this).attr('data-payment'), "order_length": products.length + menus.length, "order": JSON.stringify(products), "amount": total, "menus": JSON.stringify(menus), "listPintes": JSON.stringify(listPintes)}, function(data){
|
||||
$.post("order", {"user":id_user, "paymentMethod": $(this).attr('data-payment'), "order_length": products.length + menus.length + cotisations.length, "order": JSON.stringify(products), "amount": total, "menus": JSON.stringify(menus), "listPintes": JSON.stringify(listPintes), "cotisations": JSON.stringify(cotisations)}, function(data){
|
||||
alert(data);
|
||||
location.reload();
|
||||
}).fail(function(data){
|
||||
|
|
BIN
staticfiles/runner-assets/default_100_percent/100-disabled.png
Normal file
BIN
staticfiles/runner-assets/default_100_percent/100-disabled.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 382 B |
Binary file not shown.
After Width: | Height: | Size: 196 B |
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
Binary file not shown.
2715
staticfiles/runner.js
Normal file
2715
staticfiles/runner.js
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,5 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
{% block entete %}Page introuvable{% endblock %}
|
||||
{% block navbar %}
|
||||
<ul>
|
||||
|
@ -6,6 +7,30 @@
|
|||
</ul>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<script>
|
||||
onkeydown = function(e)
|
||||
{
|
||||
var touche = e.keyCode;
|
||||
var touche_lettre = String.fromCharCode(touche);
|
||||
gauche = false;
|
||||
haut = false;
|
||||
bas = false;
|
||||
droite = false;
|
||||
|
||||
if(touche == 37 || touche_lettre == "Q") //Le déplacement à gauche
|
||||
gauche = true;
|
||||
if(touche == 38 || touche_lettre == "Z")
|
||||
haut = true;
|
||||
if(touche == 39 || touche_lettre == "D") //Le déplacement à droite
|
||||
droite = true;
|
||||
if(touche == 40 || touche_lettre == "S") //Le déplacement en bas
|
||||
bas = true;
|
||||
|
||||
if(gauche || droite || haut || bas) // Bloquer le défilement
|
||||
e.preventDefault()
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
<section id="first" class="main">
|
||||
<header class="major">
|
||||
<h2>Erreur 404</h2>
|
||||
|
@ -13,5 +38,6 @@
|
|||
<section>
|
||||
Une erreur s'est produite lors de l'accès à cette page (la page que vous demandez n'existe pas). Vous pouvez revenir à l'accueil en cliquant <a href="{% url 'home' %}">ici</a>.
|
||||
</section>
|
||||
<object type="text/html" data="{% url 'coope-runner' %}" width="100%" height="200">
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
<link rel="icon" sizes="16x16" href="{% static 'favicon16.ico' %}" type="image/x-icon">
|
||||
<link rel="icon" sizes="32x32" href="{% static 'favicon32.ico' %}" type="image/x-icon">
|
||||
<link rel="icon" sizes="96x96" href="{% static 'favicon96.ico' %}" type="image/x-icon">
|
||||
<link rel="stylesheet" href="{%static 'css/main.css' %}" />
|
||||
<link rel="stylesheet" href="{% static 'css/main.css' %}" />
|
||||
{% block extra_css %}{% endblock %}
|
||||
{% block extra_script %}{% endblock %}
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
@ -42,5 +44,16 @@
|
|||
{% include 'footer.html'%}
|
||||
</footer>
|
||||
</div>
|
||||
{% if request.user.is_authenticated %}
|
||||
<script>
|
||||
time = {% logout_time %};
|
||||
function logout(){
|
||||
window.location.replace("{% url 'users:logout' %}");
|
||||
}
|
||||
if(time != 0){
|
||||
setTimeout(logout, 60000 * time);
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
</body>
|
||||
</html>
|
||||
|
|
86
templates/coope-runner.html
Normal file
86
templates/coope-runner.html
Normal file
File diff suppressed because one or more lines are too long
|
@ -39,6 +39,6 @@
|
|||
<li><a href="https://www.facebook.com/coopesmetz/" class="icon fa-facebook alt"><span class="label">Facebook</span></a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<p class="copyright">coope.rez v3.2.2 (release stable) © 2018 Yoann Pietri.</p>
|
||||
<p class="copyright">coope.rez v3.3.0 (release stable) © 2018 Yoann Pietri.</p>
|
||||
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
{% csrf_token %}
|
||||
{{ form }}
|
||||
<br>
|
||||
<button type="submit">{{form_button}}</button>
|
||||
<button type="submit"><i class="fa fa-{{form_button_icon}}"></i> {{form_button}}</button>
|
||||
</form>
|
||||
</section>
|
||||
</section>
|
||||
|
|
31
templates/home.html
Normal file
31
templates/home.html
Normal file
|
@ -0,0 +1,31 @@
|
|||
{% extends 'base.html' %}
|
||||
{% block entete %}Accueil{% endblock %}
|
||||
{% block navbar %}
|
||||
<ul>
|
||||
<li><a href="#first">Accueil</a></li>
|
||||
<li><a href="#second">Les pressions du moment</a></li>
|
||||
</ul>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<section id="first" class="main">
|
||||
<header class="major">
|
||||
<h2>Accueil</h2>
|
||||
</header>
|
||||
<section>
|
||||
{{ home_text }}
|
||||
</section>
|
||||
</section>
|
||||
<section id="second" class="main">
|
||||
<header class="major">
|
||||
<h2>Les pressions du moment</h2>
|
||||
</header>
|
||||
<section>
|
||||
Les bières pressions actuellement en Coopé :
|
||||
<ul>
|
||||
{% for keg in kegs %}
|
||||
<li>{{keg}} ({% if keg.pinte %} Pinte : {{keg.pinte.amount}}€,{% endif %}{% if keg.demi %} Demi : {{keg.demi.amount}}€,{% endif %}{% if keg.galopin %} Galopin : {{keg.galopin.amount}}€{% endif %}) : {{keg.pinte.deg}}°</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
{% endblock %}
|
|
@ -1,3 +1,6 @@
|
|||
<span class="tabulation2">
|
||||
<i class="fa fa-home"></i> <a href="{% url 'homepage' %}">Accueil</a>
|
||||
</span>
|
||||
{% if request.user.is_authenticated %}
|
||||
<span class="tabulation2">
|
||||
<i class="fa fa-user"></i> <a href="{% url 'users:profile' request.user.pk %}">Mon profil</a>
|
||||
|
@ -18,11 +21,11 @@
|
|||
</span>
|
||||
{% endif %}
|
||||
<span class="tabulation2">
|
||||
<br>
|
||||
<i class="fa fa-list-ol"></i> <a href="{% url 'gestion:ranking' %}">Classement</a>
|
||||
</span>
|
||||
{% if perms.preferences.change_generalpreferences %}
|
||||
<span class="tabulation2">
|
||||
<br>
|
||||
<i class="fa fa-tools"></i> <a href="{% url 'preferences:generalPreferences' %}">Admin</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
|
@ -45,5 +48,7 @@
|
|||
<i class="fa fa-bed"></i> <a href="{% url 'users:logout' %}">Deconnexion</a>
|
||||
</span>
|
||||
{% else %}
|
||||
<i class="fa fa-sign-in"></i> <a href="{% url 'users:login' %}">Connexion</a>
|
||||
<span class="tabulation2">
|
||||
<i class="fa fa-sign-in-alt"></i> <a href="{% url 'users:login' %}">Connexion</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<header class="major">
|
||||
<h2>Liste des admins</h2>
|
||||
</header>
|
||||
<a class="button" href="{% url 'users:addAdmin' %}">Ajouter un admin</a><br><br>
|
||||
<a class="button" href="{% url 'users:addAdmin' %}"><i class="fa fa-user-plus"></i> Ajouter un admin</a><br><br>
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
|
@ -23,9 +23,9 @@
|
|||
<tbody>
|
||||
{% for user in admins %}
|
||||
<tr>
|
||||
<td>{{ user }} {% if user.is_superuser %}(superuser){% endif %}</td>
|
||||
<td><a class="button small" href="{% url 'users:profile' user.pk %}">Profil</a></td>
|
||||
<td>{% if not user.is_superuser %}<a class="button small" href="{% url 'users:removeAdmin' user.pk %}">Retirer des admins</a>{% endif %}</td>
|
||||
<td><a href="{% url 'users:profile' user.pk %}">{{ user }}</a>{ {% if user.is_superuser %}(superuser){% endif %}</td>
|
||||
<td><a class="button small" href="{% url 'users:profile' user.pk %}"><i class="fa fa-user"></i> Profil</a></td>
|
||||
<td>{% if not user.is_superuser %}<a class="button small" href="{% url 'users:removeAdmin' user.pk %}"><i class="fa fa-minus-square"></i> Retirer des admins</a>{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
{% block navbar %}
|
||||
<ul>
|
||||
<li><a href="#first">Rechargements ({{user}})</a></li>
|
||||
<li><a href="#first">Rechargements (<a href="{% url 'profile:users' user.pk %}">{{user}}</a>)</a></li>
|
||||
</ul>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
{% block content %}
|
||||
<section id="first" class="main special">
|
||||
<header class="major">
|
||||
<h2>Consommations ({{user}})</h2>
|
||||
<h2>Consommations (<a href="{% url 'users:profile' user.pk %}">{{user}}</a>)</h2>
|
||||
</header>
|
||||
<section id="rechargements">
|
||||
<div class="table-wrapper">
|
||||
|
@ -28,7 +28,7 @@
|
|||
<tbody id="bodyTransaction">
|
||||
{% for c in consumptions %}
|
||||
<tr>
|
||||
<td>{{c.product}}</td>
|
||||
<td>{% if perms.gestion.view_product %}<a href="{% url 'gestion:productProfile' c.product.pk %}">{{ c.product.name }}{% else %}{{c.product.name}}{% endif %}</a></td>
|
||||
<td>{{c.quantity}}</td>
|
||||
<td>{{c.amount}}</td>
|
||||
<td>{{c.paymentMethod}}</td>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
{% block content %}
|
||||
<section id="first" class="main special">
|
||||
<header class="major">
|
||||
<h2>Consommations de menus ({{user}})</h2>
|
||||
<h2>Consommations de menus (<a href="{% url 'profile:users' user.pk %}">{{user}}</a>)</h2>
|
||||
</header>
|
||||
<section id="rechargements">
|
||||
<div class="table-wrapper">
|
||||
|
|
|
@ -21,12 +21,12 @@
|
|||
<div class="row">
|
||||
{% if perms.auth.change_group %}
|
||||
<div class="6u">
|
||||
<a class="button" href="{% url 'users:editGroup' group.pk %}">Éditer</a>
|
||||
<a class="button" href="{% url 'users:editGroup' group.pk %}"><i class="fa fa-pencil-alt"></i> Éditer</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if perms.auth.delete_group %}
|
||||
<div class="6u">
|
||||
<a class="button" href="{% url 'users:deleteGroup' group.pk %}">Supprimer</a>
|
||||
<a class="button" href="{% url 'users:deleteGroup' group.pk %}"><i class="fa fa-trash"></i> Supprimer</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
@ -49,7 +49,7 @@
|
|||
<tr>
|
||||
<td>{{perm.codename}}</td>
|
||||
<td>{{perm.name}}</td>
|
||||
<td><a class="button small" href="{% url 'users:removeRight' group.pk perm.pk %}">Enlever le droit</a></td>
|
||||
<td><a class="button small" href="{% url 'users:removeRight' group.pk perm.pk %}"><i class="fa fa-minus-square"></i> Enlever le droit</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
@ -72,9 +72,9 @@
|
|||
<tbody>
|
||||
{% for user in group.user_set.all %}
|
||||
<tr>
|
||||
<td>{{ user }}</td>
|
||||
<td><a class="button small" href="{% url 'users:profile' user.pk %}">Profil</a></td>
|
||||
<td><a class="button small" href="{% url 'users:removeUser' group.pk user.pk %}">Retirer</a></td>
|
||||
<td><a href="{% url 'users:profile' user.pk %}">{{user}}</a></td>
|
||||
<td><a class="button small" href="{% url 'users:profile' user.pk %}"><i class="fa fa-user"></i> Profil</a></td>
|
||||
<td><a class="button small" href="{% url 'users:removeUser' group.pk user.pk %}"><i class="fa fa-minus-square"></i> Retirer</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<h2>Liste des groupes de droit</h2>
|
||||
</header>
|
||||
{% if perms.auth.add_group %}
|
||||
<a href="{% url 'users:createGroup' %}" class="button">Ajouter un groupe de droit</a><br><br>
|
||||
<a href="{% url 'users:createGroup' %}" class="button"><i class="fa fa-plus-square"></i> Ajouter un groupe de droit</a><br><br>
|
||||
{% endif %}
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
|
@ -29,7 +29,7 @@
|
|||
<td>{{ group.name }}</td>
|
||||
<td>{{ group.permissions.count }}</td>
|
||||
<td>{{ group.user_set.count }}</td>
|
||||
<td><a href="{% url 'users:groupProfile' group.pk %}" class="button small">Voir</a> {% if perms.auth.change_group %}<a href="{% url 'users:editGroup' group.pk %}" class="button small">Éditer</a> {% endif %}{% if perms.auth.delete_group %}<a href="{% url 'users:deleteGroup' group.pk %}" class="button small">Supprimer</a>{% endif %}</td>
|
||||
<td><a href="{% url 'users:groupProfile' group.pk %}" class="button small"><i class="fa fa-eye"></i> Voir</a> {% if perms.auth.change_group %}<a href="{% url 'users:editGroup' group.pk %}" class="button small"><i class="fa fa-pencil-alt"></i> Éditer</a> {% endif %}{% if perms.auth.delete_group %}<a href="{% url 'users:deleteGroup' group.pk %}" class="button small"><i class="fa fa-trash"></i> Supprimer</a>{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
|
@ -107,7 +107,7 @@
|
|||
{% csrf_token %}
|
||||
{{export_form}}
|
||||
<br>
|
||||
<button class="button" target="_blank">Exporter au format csv</button>
|
||||
<button class="button" target="_blank"><i class="fa fa-file-csv"></i> Exporter au format csv</button>
|
||||
</form>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
{% load static %}
|
||||
{% load users_extra %}
|
||||
{% block entete %}{% if self %}Mon Profil{% else %}Profil de {{user}}{% endif %}{%endblock%}
|
||||
|
||||
{% block extra_script %}<script src="{% static 'jquery.js' %}"></script>{% endblock %}
|
||||
{% block navbar %}
|
||||
<ul>
|
||||
<li><a href="#first">{% if self %}Mes informations {% else %} Informations {% endif %}</a>
|
||||
|
@ -52,19 +52,19 @@
|
|||
<ul class="alt">
|
||||
<li>
|
||||
{% if self or perms.users.can_change_user %}
|
||||
<span><a href="{% url 'users:editUser' user.pk %}">Modifier {{self | yesno:"mes,les"}} informations</a></span>
|
||||
<span><a href="{% url 'users:editUser' user.pk %}"><i class="fa fa-pencil-alt"></i> Modifier {{self | yesno:"mes,les"}} informations</a></span>
|
||||
{% endif %}
|
||||
{% if self %}
|
||||
<span class="tabulation"><a href="{% url 'users:editPassword' user.pk %}">Changer mon mot de passe</a></span>
|
||||
<span class="tabulation"><a href="{% url 'users:editPassword' user.pk %}"><i class="fa fa-user-lock"></i> Changer mon mot de passe</a></span>
|
||||
{% endif %}
|
||||
{% if perms.users.can_reset_password %}
|
||||
<span class="tabulation"><a href="{% url 'users:resetPassword' user.pk %}">Réinitialiser le mot de passe</a></span>
|
||||
<span class="tabulation"><a href="{% url 'users:resetPassword' user.pk %}"><i class="fa fa-lock-open"></i> Réinitialiser le mot de passe</a></span>
|
||||
{% endif %}
|
||||
{% if perms.users.can_change_user_perm %}
|
||||
<span class="tabulation"><a href="{% url 'users:editGroups' user.pk %}">Changer les groupes</a></span>
|
||||
<span class="tabulation"><a href="{% url 'users:editGroups' user.pk %}"><i class="fa fa-layer-group"></i> Changer les groupes</a></span>
|
||||
{% endif %}
|
||||
{% if perms.auth.change_user %}
|
||||
<span class="tabulation"><a href="{% url 'users:switchActivateUser' user.pk %}">{{ user.is_active | yesno:"Désa,A"}}ctiver</a></span>
|
||||
<span class="tabulation"><a href="{% url 'users:switchActivateUser' user.pk %}"><i class="fa fa-check-circle"></i> {{ user.is_active | yesno:"Désa,A"}}ctiver</a></span>
|
||||
{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -76,6 +76,15 @@
|
|||
<script src="{% static 'chart.min.js' %}"></script>
|
||||
<script>
|
||||
var ctx = document.getElementById("myChart").getContext('2d');
|
||||
baseColor = Math.round(Math.random()*255) + "," + Math.round(Math.random()*255) + "," + Math.round(Math.random()*255);
|
||||
console.log(baseColor)
|
||||
$.get("http://www.thecolorapi.com/scheme?rgb=" + baseColor + "&mode=analogic&count={{products | length}}", function( data ) {
|
||||
colors = data.colors
|
||||
var bgColor = []
|
||||
for(var i = 0; i < colors.length; i++){
|
||||
color = colors[i]
|
||||
bgColor.push("rgb(" + color.rgb.r + "," + color.rgb.g + "," + color.rgb.b + ")")
|
||||
}
|
||||
var myChart = new Chart(ctx, {
|
||||
type: 'pie',
|
||||
data: {
|
||||
|
@ -83,11 +92,7 @@
|
|||
datasets: [{
|
||||
label: '# of Votes',
|
||||
data: [{% for q in quantities %}{{q}}, {% endfor %}],
|
||||
backgroundColor: [
|
||||
{% for q in products %}
|
||||
'rgb({% random_filter 0 255 %}, {% random_filter 0 255 %}, {% random_filter 0 255 %})',
|
||||
{% endfor %}
|
||||
],
|
||||
backgroundColor: bgColor
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
|
@ -100,6 +105,7 @@
|
|||
}
|
||||
}
|
||||
});
|
||||
}, "json" );
|
||||
</script>
|
||||
</section>
|
||||
</section>
|
||||
|
@ -124,12 +130,12 @@
|
|||
<tbody id="bodyTransaction">
|
||||
{% for c in lastConsumptions %}
|
||||
<tr>
|
||||
<td>{{c.product}}</td>
|
||||
<td>{% if perms.gestion.view_product %}<a href="{% url 'gestion:productProfile' c.product.pk %}">{{ c.product.name }}</a>{% else %}{{c.product}}{% endif %}</td>
|
||||
<td>{{c.quantity}}</td>
|
||||
<td>{{c.amount}} €</td>
|
||||
<td>{{c.paymentMethod}}</td>
|
||||
<td>{{c.date}}</td>
|
||||
<td>{% if perms.gestion.delete_consumptionhistory %}<a href="{% url 'gestion:cancelConsumption' c.pk %}" class="button small">Annuler</a>{% endif %}</td>
|
||||
<td>{% if perms.gestion.delete_consumptionhistory %}<a href="{% url 'gestion:cancelConsumption' c.pk %}" class="button small"><i class="fa fa-times"></i> Annuler</a>{% endif %}</td>
|
||||
</tr>
|
||||
{%endfor%}
|
||||
</tbody>
|
||||
|
@ -163,7 +169,7 @@
|
|||
<td>{{m.amount}} €</td>
|
||||
<td>{{m.paymentMethod}}</td>
|
||||
<td>{{m.date}}</td>
|
||||
<td>{% if perms.gestion.delete_menuhistory %}<a href="{% url 'gestion:cancelMenu' m.pk %}" class="button small">Annuler</a>{% endif %}</td>
|
||||
<td>{% if perms.gestion.delete_menuhistory %}<a href="{% url 'gestion:cancelMenu' m.pk %}" class="button small"><i class="fa fa-times"></i> Annuler</a>{% endif %}</td>
|
||||
</tr>
|
||||
{%endfor%}
|
||||
</tbody>
|
||||
|
@ -196,7 +202,7 @@
|
|||
<td>{{reload.PaymentMethod}}</td>
|
||||
<td>{{reload.date}}</td>
|
||||
{% if perms.gestion.delete_reload %}
|
||||
<th><a href="{% url 'gestion:cancelReload' reload.pk %}" class="button small">Annuler</a></th>
|
||||
<th><a href="{% url 'gestion:cancelReload' reload.pk %}" class="button small"><i class="fa fa-times"></i> Annuler</a></th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -211,7 +217,7 @@
|
|||
<h2>{{ self | yesno:"Mes cotisations,Cotisations"}}</h2>
|
||||
</header>
|
||||
<section>
|
||||
<a class="button" href="{% url 'users:addCotisationHistory' user.pk %}">Ajouter une cotisation</a><br><br>
|
||||
<a class="button" href="{% url 'users:addCotisationHistory' user.pk %}"><i class="fa fa-comments-dollar"></i> Ajouter une cotisation</a><br><br>
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
|
@ -234,7 +240,7 @@
|
|||
<td>{{cotisation.paymentMethod}}</td>
|
||||
<td>{{cotisation.endDate}}</td>
|
||||
<td>{{cotisation.valid}}</td>
|
||||
<td>{% if perms.users.validate_cotisationHistory %}<a class="button small" href="{% url 'users:validateCotisationHistory' cotisation.pk %}">Valider</a> <a class="button small" href="{% url 'users:invalidateCotisationHistory' cotisation.pk %}">Invalider</a>{% endif %}</td>
|
||||
<td>{% if perms.users.validate_cotisationHistory %}<a class="button small" href="{% url 'users:validateCotisationHistory' cotisation.pk %}"><i class="fa fa-check-circle"></i> Valider</a> <a class="button small" href="{% url 'users:invalidateCotisationHistory' cotisation.pk %}"><i class="fa fa-times-circle"></i> Invalider</a>{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
@ -248,7 +254,7 @@
|
|||
<h2>{{ self | yesno:"Mes accès gracieux,Accès gracieux"}}</h2>
|
||||
</header>
|
||||
<section>
|
||||
<a class="button" href="{% url 'users:addWhiteListHistory' user.pk %}">Ajouter un accès à titre gracieux</a><br><br>
|
||||
<a class="button" href="{% url 'users:addWhiteListHistory' user.pk %}"><i class="fa fa-handshake"></i> Ajouter un accès à titre gracieux</a><br><br>
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<header class="major">
|
||||
<h2>Liste des écoles</h2>
|
||||
</header>
|
||||
<a class="button" href="{% url 'users:createSchool' %}">Créer une école</a><br><br>
|
||||
<a class="button" href="{% url 'users:createSchool' %}"><i class="fa fa-school"></i> Créer une école</a><br><br>
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
|
@ -23,7 +23,7 @@
|
|||
{% for school in schools %}
|
||||
<tr>
|
||||
<td>{{ school }}</td>
|
||||
<td>{% if perms.gestion.change_school %}<a class="button small" href="{% url 'users:editSchool' school.pk %}">Modifier</a> {% endif %}{% if perms.gestion.delete_school %}<a class="button small" href="{% url 'users:deleteSchool' school.pk %}">Supprimer</a>{% endif %}</td>
|
||||
<td>{% if perms.gestion.change_school %}<a class="button small" href="{% url 'users:editSchool' school.pk %}"><i class="fa fa-pencil-alt"></i> Modifier</a> {% endif %}{% if perms.gestion.delete_school %}<a class="button small" href="{% url 'users:deleteSchool' school.pk %}"><i class="fa fa-trash"></i> Supprimer</a>{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<header class="major">
|
||||
<h2>Liste des superusers</h2>
|
||||
</header>
|
||||
<a class="button" href="{% url 'users:addSuperuser' %}">Ajouter un superuser</a><br><br>
|
||||
<a class="button" href="{% url 'users:addSuperuser' %}"><i class="fa fa-user-plus"></i> Ajouter un superuser</a><br><br>
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
|
@ -23,9 +23,9 @@
|
|||
<tbody>
|
||||
{% for user in superusers %}
|
||||
<tr>
|
||||
<td>{{ user }}</td>
|
||||
<td><a class="button small" href="{% url 'users:profile' user.pk %}">Profil</a></td>
|
||||
<td><a class="button small" href="{% url 'users:removeSuperuser' user.pk %}">Retirer des superusers</a></td>
|
||||
<td><a href="{% url 'users:profile' user.pk %}">{{user}}</a></td>
|
||||
<td><a class="button small" href="{% url 'users:profile' user.pk %}"><i class="fa fa-user"></i> Profil</a></td>
|
||||
<td><a class="button small" href="{% url 'users:removeSuperuser' user.pk %}"><i class="fa fa-minus-square"></i> Retirer des superusers</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<header class="major">
|
||||
<h2>Liste des utilisateurs</h2>
|
||||
</header>
|
||||
<a class="button" href="{% url 'users:createUser' %}">Créer un utilisateur</a><br><br>
|
||||
<a class="button" href="{% url 'users:createUser' %}"><i class="fa fa-user-plus"></i> Créer un utilisateur</a><br><br>
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
|
@ -25,10 +25,10 @@
|
|||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr>
|
||||
<td>{{ user }}</td>
|
||||
<td><a class="button small" href="{% url 'users:profile' user.pk %}">Profil</a></td>
|
||||
<td><a href="{% url 'users:profile' user.pk %}">{{user}}</a></td>
|
||||
<td><a class="button small" href="{% url 'users:profile' user.pk %}"><i class="fa fa-user"></i> Profil</a></td>
|
||||
{% if perms.auth.change_user %}
|
||||
<td><a class="button small" href="{% url 'users:switchActivateUser' user.pk %}">{{ user.is_active | yesno:"Désa,A"}}ctiver</a></td>
|
||||
<td><a class="button small" href="{% url 'users:switchActivateUser' user.pk %}">{% if user.is_active %}<i class="fa fa-times-circle"></i> Désactiver{% else %}<i class="fa fa-check-circle"></i> Activer{% endif %}</a></td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
|
|
@ -52,7 +52,7 @@ def loginView(request):
|
|||
return redirect(reverse('users:profile', kwargs={'pk':request.user.pk}))
|
||||
else:
|
||||
messages.error(request, "Nom d'utilisateur et/ou mot de passe invalide")
|
||||
return render(request, "form.html", {"form_entete": "Connexion", "form": form, "form_title": "Connexion", "form_button": "Se connecter"})
|
||||
return render(request, "form.html", {"form_entete": "Connexion", "form": form, "form_title": "Connexion", "form_button": "Se connecter", "form_button_icon": "sign-in-alt"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -225,7 +225,7 @@ def createUser(request):
|
|||
user.save()
|
||||
messages.success(request, "L'utilisateur a bien été créé")
|
||||
return redirect(reverse('users:profile', kwargs={'pk':user.pk}))
|
||||
return render(request, "form.html", {"form_entete": "Gestion des utilisateurs", "form":form, "form_title":"Création d'un nouvel utilisateur", "form_button":"Créer l'utilisateur"})
|
||||
return render(request, "form.html", {"form_entete": "Gestion des utilisateurs", "form":form, "form_title":"Création d'un nouvel utilisateur", "form_button":"Créer l'utilisateur", "form_button_icon": "user-plus"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -252,7 +252,7 @@ def searchUser(request):
|
|||
form = SelectUserForm(request.POST or None)
|
||||
if(form.is_valid()):
|
||||
return redirect(reverse('users:profile', kwargs={"pk":form.cleaned_data['user'].pk}))
|
||||
return render(request, "form.html", {"form_entete": "Gestion des utilisateurs", "form": form, "form_title": "Rechercher un utilisateur", "form_button": "Afficher le profil"})
|
||||
return render(request, "form.html", {"form_entete": "Gestion des utilisateurs", "form": form, "form_title": "Rechercher un utilisateur", "form_button": "Afficher le profil", "form_button_icon": "search"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -305,7 +305,7 @@ def editGroups(request, pk):
|
|||
messages.success(request, "Les groupes de l'utilisateur " + user.username + " ont bien été enregistrés.")
|
||||
return redirect(reverse('users:profile', kwargs={'pk':pk}))
|
||||
extra_css = "#id_groups{height:200px;}"
|
||||
return render(request, "form.html", {"form_entete": "Gestion de l'utilisateur " + user.username, "form": form, "form_title": "Modification des groupes", "form_button": "Enregistrer", "extra_css": extra_css})
|
||||
return render(request, "form.html", {"form_entete": "Gestion de l'utilisateur " + user.username, "form": form, "form_title": "Modification des groupes", "form_button": "Enregistrer", "form_button_icon": "pencil-alt", "extra_css": extra_css})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -345,7 +345,7 @@ def editPassword(request, pk):
|
|||
return redirect(reverse('users:profile', kwargs={'pk':pk}))
|
||||
else:
|
||||
messages.error(request, "Le mot de passe actuel est incorrect")
|
||||
return render(request, "form.html", {"form_entete": "Modification de mon compte", "form": form, "form_title": "Modification de mon mot de passe", "form_button": "Modifier mon mot de passe"})
|
||||
return render(request, "form.html", {"form_entete": "Modification de mon compte", "form": form, "form_title": "Modification de mon mot de passe", "form_button": "Modifier mon mot de passe", "form_button_icon": "pencil-alt"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -379,7 +379,7 @@ def editUser(request, pk):
|
|||
user.save()
|
||||
messages.success(request, "Les modifications ont bien été enregistrées")
|
||||
return redirect(reverse('users:profile', kwargs={'pk': pk}))
|
||||
return render(request, "form.html", {"form_entete":"Modification du compte " + user.username, "form": form, "form_title": "Modification des informations", "form_button": "Modifier"})
|
||||
return render(request, "form.html", {"form_entete":"Modification du compte " + user.username, "form": form, "form_title": "Modification des informations", "form_button": "Modifier", "form_button_icon": "pencil-alt"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -413,7 +413,7 @@ def getUser(request, pk):
|
|||
The pk of the user
|
||||
"""
|
||||
user = get_object_or_404(User, pk=pk)
|
||||
data = json.dumps({"username": user.username, "balance": user.profile.balance})
|
||||
data = json.dumps({"username": user.username, "balance": user.profile.balance, "is_adherent": user.profile.is_adherent})
|
||||
return HttpResponse(data, content_type='application/json')
|
||||
|
||||
@active_required
|
||||
|
@ -583,7 +583,7 @@ def createGroup(request):
|
|||
group = form.save()
|
||||
messages.success(request, "Le groupe " + form.cleaned_data['name'] + " a bien été crée.")
|
||||
return redirect(reverse('users:groupProfile', kwargs={'pk': group.pk}))
|
||||
return render(request, "form.html", {"form_entete": "Gestion des utilisateurs", "form":form, "form_title": "Création d'un groupe de droit", "form_button": "Créer le groupe de droit"})
|
||||
return render(request, "form.html", {"form_entete": "Gestion des utilisateurs", "form":form, "form_title": "Création d'un groupe de droit", "form_button": "Créer le groupe de droit", "form_button_icon": "plus-square"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -617,7 +617,7 @@ def editGroup(request, pk):
|
|||
form.save()
|
||||
messages.success(request, "Le groupe " + group.name + " a bien été modifié.")
|
||||
return redirect(reverse('users:groupProfile', kwargs={'pk': group.pk}))
|
||||
return render(request, "form.html", {"form_entete": "Gestion des utilisateurs", "form": form, "form_title": "Modification du groupe de droit " + group.name, "form_button": "Modifier le groupe de droit", "extra_css":extra_css})
|
||||
return render(request, "form.html", {"form_entete": "Gestion des utilisateurs", "form": form, "form_title": "Modification du groupe de droit " + group.name, "form_button": "Modifier le groupe de droit", "form_button_icon": "pencil-alt", "extra_css":extra_css})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -736,7 +736,7 @@ def addAdmin(request):
|
|||
user.save()
|
||||
messages.success(request, "L'utilisateur " + user.username + " a bien été rajouté aux admins")
|
||||
return redirect(reverse('users:adminsIndex'))
|
||||
return render(request, "form.html", {"form": form, "form_title": "Ajout d'un admin", "form_button":"Ajouter l'utilisateur aux admins"})
|
||||
return render(request, "form.html", {"form": form, "form_title": "Ajout d'un admin", "form_button": "Ajouter l'utilisateur aux admins", "form_button_icon": "user-plus"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -814,7 +814,7 @@ def addSuperuser(request):
|
|||
user.save()
|
||||
messages.success(request, "L'utilisateur " + user.username + " a bien été rajouté aux superusers")
|
||||
return redirect(reverse('users:superusersIndex'))
|
||||
return render(request, "form.html", {"form_entete": "Gestion des superusers", "form": form, "form_title": "Ajout d'un superuser", "form_button":"Ajouter l'utilisateur aux superusers"})
|
||||
return render(request, "form.html", {"form_entete": "Gestion des superusers", "form": form, "form_title": "Ajout d'un superuser", "form_button":"Ajouter l'utilisateur aux superusers", "form_button_icon": "user-plus"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -888,7 +888,7 @@ def addCotisationHistory(request, pk):
|
|||
cotisation.save()
|
||||
messages.success(request, "La cotisation a bien été ajoutée")
|
||||
return redirect(reverse('users:profile',kwargs={'pk':user.pk}))
|
||||
return render(request, "form.html",{"form": form, "form_title": "Ajout d'une cotisation pour l'utilisateur " + str(user), "form_button": "Ajouter"})
|
||||
return render(request, "form.html",{"form": form, "form_title": "Ajout d'une cotisation pour l'utilisateur " + str(user), "form_button": "Ajouter", "form_button_icon": "plus-square"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -922,7 +922,7 @@ def invalidateCotisationHistory(request, pk):
|
|||
user = cotisationHistory.user
|
||||
user.profile.cotisationEnd = user.profile.cotisationEnd - timedelta(days=cotisationHistory.duration)
|
||||
if(cotisationHistory.paymentMethod.affect_balance):
|
||||
user.profile.balance += cotisation.amount
|
||||
user.profile.debit -= cotisationHistory.cotisation.amount
|
||||
user.save()
|
||||
messages.success(request, "La cotisation a bien été invalidée")
|
||||
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
|
||||
|
@ -969,7 +969,7 @@ def addWhiteListHistory(request, pk):
|
|||
whiteList.save()
|
||||
messages.success(request, "L'accès gracieux a bien été ajouté")
|
||||
return redirect(reverse('users:profile', kwargs={'pk':user.pk}))
|
||||
return render(request, "form.html", {"form": form, "form_title": "Ajout d'un accès gracieux pour " + user.username, "form_button": "Ajouter"})
|
||||
return render(request, "form.html", {"form": form, "form_title": "Ajout d'un accès gracieux pour " + user.username, "form_button": "Ajouter", "form_button_icon": "plus-square"})
|
||||
|
||||
########## Schools ##########
|
||||
|
||||
|
@ -1019,7 +1019,7 @@ def createSchool(request):
|
|||
form.save()
|
||||
messages.success(request, "L'école a bien été créée")
|
||||
return redirect(reverse('users:schoolsIndex'))
|
||||
return render(request, "form.html", {"form": form, "form_title": "Création d'une école", "form_button": "Créer"})
|
||||
return render(request, "form.html", {"form": form, "form_title": "Création d'une école", "form_button": "Créer", "form_button_icon": "plus-square"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -1052,7 +1052,7 @@ def editSchool(request, pk):
|
|||
form.save()
|
||||
messages.success(request, "L'école a bien été modifiée")
|
||||
return redirect(reverse('users:schoolsIndex'))
|
||||
return render(request, "form.html", {"form": form, "form_title": "Modification de l'école " + str(school), "form_button": "Modifier"})
|
||||
return render(request, "form.html", {"form": form, "form_title": "Modification de l'école " + str(school), "form_button": "Modifier", "form_button": "pencil-alt"})
|
||||
|
||||
@active_required
|
||||
@login_required
|
||||
|
@ -1079,7 +1079,7 @@ class AllUsersAutocomplete(autocomplete.Select2QuerySetView):
|
|||
def get_queryset(self):
|
||||
qs = User.objects.all()
|
||||
if self.q:
|
||||
qs = qs.filter(Q(username__istartswith=self.q) | Q(first_name__istartswith=self.q) | Q(last_name__istartswith=self.q))
|
||||
qs = qs.filter(Q(username__contains=self.q) | Q(first_name__contains=self.q) | Q(last_name__contains=self.q))
|
||||
return qs
|
||||
|
||||
class ActiveUsersAutocomplete(autocomplete.Select2QuerySetView):
|
||||
|
@ -1089,7 +1089,7 @@ class ActiveUsersAutocomplete(autocomplete.Select2QuerySetView):
|
|||
def get_queryset(self):
|
||||
qs = User.objects.filter(is_active=True)
|
||||
if self.q:
|
||||
qs = qs.filter(Q(username__istartswith=self.q) | Q(first_name__istartswith=self.q) | Q(last_name__istartswith=self.q))
|
||||
qs = qs.filter(Q(username__contains=self.q) | Q(first_name__contains=self.q) | Q(last_name__contains=self.q))
|
||||
return qs
|
||||
|
||||
class AdherentAutocomplete(autocomplete.Select2QuerySetView):
|
||||
|
@ -1098,8 +1098,13 @@ class AdherentAutocomplete(autocomplete.Select2QuerySetView):
|
|||
"""
|
||||
def get_queryset(self):
|
||||
qs = User.objects.all()
|
||||
pks = [x.pk for x in qs if x.is_adherent]
|
||||
qs = User.objects.filter(pk__in=pks)
|
||||
if self.q:
|
||||
qs = qs.filter(Q(username__contains=self.q) | Q(first_name__contains=self.q) | Q(last_name__contains=self.q))
|
||||
return qs
|
||||
|
||||
|
||||
class NonSuperUserAutocomplete(autocomplete.Select2QuerySetView):
|
||||
"""
|
||||
Autocomplete for non-superuser users
|
||||
|
@ -1107,7 +1112,7 @@ class NonSuperUserAutocomplete(autocomplete.Select2QuerySetView):
|
|||
def get_queryset(self):
|
||||
qs = User.objects.filter(is_superuser=False)
|
||||
if self.q:
|
||||
qs = qs.filter(Q(username__istartswith=self.q) | Q(first_name__istartswith=self.q) | Q(last_name__istartswith=self.q))
|
||||
qs = qs.filter(Q(username__contains=self.q) | Q(first_name__contains=self.q) | Q(last_name__contains=self.q))
|
||||
return qs
|
||||
|
||||
class NonAdminUserAutocomplete(autocomplete.Select2QuerySetView):
|
||||
|
@ -1117,5 +1122,5 @@ class NonAdminUserAutocomplete(autocomplete.Select2QuerySetView):
|
|||
def get_queryset(self):
|
||||
qs = User.objects.filter(is_staff=False)
|
||||
if self.q:
|
||||
qs = qs.filter(Q(username__istartswith=self.q) | Q(first_name__istartswith=self.q) | Q(last_name__istartswith=self.q))
|
||||
qs = qs.filter(Q(username__contains=self.q) | Q(first_name__contains=self.q) | Q(last_name__contains=self.q))
|
||||
return qs
|
Loading…
Reference in a new issue