Browse Source

Add divide vie and DivideHisotry model

pull/1/head
Yoann Piétri 7 years ago
parent
commit
0fd8f2d419
  1. 77
      gestion/templates/gestion/divide.html
  2. 1
      gestion/urls.py
  3. 36
      gestion/views.py
  4. 12
      preferences/admin.py
  5. 6
      preferences/forms.py
  6. 23
      preferences/migrations/0013_auto_20190622_2334.py
  7. 17
      preferences/migrations/0014_auto_20190623_0957.py
  8. 30
      preferences/migrations/0015_dividehistory.py
  9. 39
      preferences/models.py
  10. 2
      preferences/templates/preferences/cotisations_index.html
  11. 9
      templates/nav.html
  12. 42
      users/migrations/0007_auto_20190623_0957.py
  13. 8
      users/models.py
  14. 1
      users/views.py

77
gestion/templates/gestion/divide.html

@ -0,0 +1,77 @@
{% extends 'base.html' %}
{% block entete %}Répartition des cotisations{% endblock %}
{% block navbar %}
<ul>
<li><a href="#first">Répartition des cotisations</a></li>
<li><a href="#second">Historique des répartitions</a></li>
</ul>
{% endblock %}
{% block content %}
<section id="first" class="main">
<header class="major">
<h2>Répartition des cotisations</h2>
</header>
<section>
<div class="table-wrapper">
<table>
<thead>
<tr>
<th>Champ</th>
<th>Valeur</th>
</tr>
</thead>
<tbody>
<tr>
<td>Nombre de cotisations non réparties</td>
<td>{{total_cotisations}}</td>
</tr>
<tr>
<td>Valeur totale des cotisations non réparties</td>
<td>{{total_amount}} €</td>
</tr>
<tr>
<td>Valeur à donner au Club Phœnix Technopôle Metz</td>
<td>{{total_amount_ptm}} €</td>
</tr>
</tbody>
</table>
</div>
<form action="" method="post">
{% csrf_token %}
<button type="submit"><i class="fa fa-hand-holding-usd"></i> Répartir</button>
</form>
<p>Attention, cliquer sur ce bouton marquera toutes les cotisations actuellement non réparties comme réparties. L'historique de cette action n'est pas simple à obtenir et l'action peut être considérée comme irreversible.</p>
</section>
</section>
<section id="second" class="main">
<header class="major">
<h2>Historique des répartitions</h2>
</header>
<section>
<div class="table-wrapper">
<table>
<thead>
<tr>
<th>Date</th>
<th>Nombre de cotisations</th>
<th>Montant des cotisations</th>
<th>Montant des cotisations pourle Phœnix</th>
<th>Coopeman</th>
</tr>
</thead>
<tbody>
{% for divide_history in divide_histories %}
<tr>
<td>{{ divide_history.date }}</td>
<td>{{ divide_history.total_cotisations }}</td>
<td>{{ divide_history.total_cotisations_amount }} €</td>
<td>{{ divide_history.total_ptm_amount }} €</td>
<td>{{ divide_history.coopeman }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</section>
</section>
{% endblock %}

1
gestion/urls.py

@ -53,4 +53,5 @@ urlpatterns = [
path('categoriesList', views.categoriesList, name="categoriesList"), path('categoriesList', views.categoriesList, name="categoriesList"),
path('categories-autocomplete', views.CategoriesAutocomplete.as_view(), name="categories-autocomplete"), path('categories-autocomplete', views.CategoriesAutocomplete.as_view(), name="categories-autocomplete"),
path('stats', views.stats, name="stats"), path('stats', views.stats, name="stats"),
path('divide', views.divide, name="divide"),
] ]

36
gestion/views.py

@ -21,7 +21,7 @@ from decimal import *
from .forms import ReloadForm, RefundForm, ProductForm, KegForm, MenuForm, GestionForm, SearchMenuForm, SearchProductForm, SelectPositiveKegForm, SelectActiveKegForm, PinteForm, GenerateReleveForm, CategoryForm, SearchCategoryForm from .forms import ReloadForm, RefundForm, ProductForm, KegForm, MenuForm, GestionForm, SearchMenuForm, SearchProductForm, SelectPositiveKegForm, SelectActiveKegForm, PinteForm, GenerateReleveForm, CategoryForm, SearchCategoryForm
from .models import Product, Menu, Keg, ConsumptionHistory, KegHistory, Consumption, MenuHistory, Pinte, Reload, Refund, Category from .models import Product, Menu, Keg, ConsumptionHistory, KegHistory, Consumption, MenuHistory, Pinte, Reload, Refund, Category
from users.models import School from users.models import School
from preferences.models import PaymentMethod, GeneralPreferences, Cotisation from preferences.models import PaymentMethod, GeneralPreferences, Cotisation, DivideHistory
from users.models import CotisationHistory from users.models import CotisationHistory
@active_required @active_required
@ -877,7 +877,39 @@ def gen_releve(request):
else: else:
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"}) 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"})
@active_required
@login_required
@permission_required('preferences.can_divide')
def divide(request):
"""
Divide all non-divided cotisation
"""
if request.POST:
non_divided_cotisations = CotisationHistory.objects.filter(divided=False)
for cotisation_history in non_divided_cotisations:
cotisation_history.divided = True
cotisation_history.save()
divide_history = DivideHistory(
total_cotisations = non_divided_cotisations.count(),
total_cotisations_amount = sum([x.amount for x in non_divided_cotisations]),
total_ptm_amount = sum([x.amount_ptm for x in non_divided_cotisations]),
coopeman = request.user
)
divide_history.save()
non_divided_cotisations = CotisationHistory.objects.filter(divided=False)
total_amount = sum([x.amount for x in non_divided_cotisations])
total_amount_ptm = sum([x.amount_ptm for x in non_divided_cotisations])
divide_histories = DivideHistory.objects.all().order_by('-date')
return render(
request,
"gestion/divide.html",
{
"total_cotisations": non_divided_cotisations.count(),
"total_amount": total_amount,
"total_amount_ptm": total_amount_ptm,
"divide_histories": divide_histories,
}
)
########## categories ########## ########## categories ##########
@active_required @active_required
@login_required @login_required

12
preferences/admin.py

@ -1,6 +1,6 @@
from django.contrib import admin from django.contrib import admin
from simple_history.admin import SimpleHistoryAdmin from simple_history.admin import SimpleHistoryAdmin
from .models import PaymentMethod, GeneralPreferences, Cotisation from .models import PaymentMethod, GeneralPreferences, Cotisation, DivideHistory
class CotisationAdmin(SimpleHistoryAdmin): class CotisationAdmin(SimpleHistoryAdmin):
""" """
@ -24,6 +24,14 @@ class PaymentMethodAdmin(SimpleHistoryAdmin):
search_fields = ('name',) search_fields = ('name',)
list_filter = ('is_active', 'is_usable_in_cotisation', 'is_usable_in_reload', 'affect_balance') list_filter = ('is_active', 'is_usable_in_cotisation', 'is_usable_in_reload', 'affect_balance')
class DivideHistoryAdmin(SimpleHistoryAdmin):
"""
The admin class for Divide histories
"""
list_display = ('date', 'total_cotisations', 'total_cotisations_amount', 'total_ptm_amount', 'coopeman')
ordering = ('-date',)
admin.site.register(PaymentMethod, PaymentMethodAdmin) admin.site.register(PaymentMethod, PaymentMethodAdmin)
admin.site.register(GeneralPreferences, GeneralPreferencesAdmin) admin.site.register(GeneralPreferences, GeneralPreferencesAdmin)
admin.site.register(Cotisation, CotisationAdmin) admin.site.register(Cotisation, CotisationAdmin)
admin.site.register(DivideHistory, DivideHistoryAdmin)

6
preferences/forms.py

@ -11,6 +11,12 @@ class CotisationForm(forms.ModelForm):
model = Cotisation model = Cotisation
fields = "__all__" fields = "__all__"
def clean(self):
cleaned_data = super().clean()
if cleaned_data.get("amount_ptm") > cleaned_data.get("amount"):
raise ValidationError("La quantité d'argent donnée au club doit être inférieure à\
la quantité d'argent totale")
class PaymentMethodForm(forms.ModelForm): class PaymentMethodForm(forms.ModelForm):
""" """
Form to add and edit :class:`~preferences.models.PaymentMethod`. Form to add and edit :class:`~preferences.models.PaymentMethod`.

23
preferences/migrations/0013_auto_20190622_2334.py

@ -0,0 +1,23 @@
# Generated by Django 2.1 on 2019-06-22 21:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('preferences', '0012_auto_20190428_1327'),
]
operations = [
migrations.AddField(
model_name='cotisation',
name='amount_ptm',
field=models.DecimalField(decimal_places=2, max_digits=5, null=True, verbose_name='Montant pour le club Phœnix Technopôle Metz'),
),
migrations.AddField(
model_name='historicalcotisation',
name='amount_ptm',
field=models.DecimalField(decimal_places=2, max_digits=5, null=True, verbose_name='Montant pour le club Phœnix Technopôle Metz'),
),
]

17
preferences/migrations/0014_auto_20190623_0957.py

@ -0,0 +1,17 @@
# Generated by Django 2.1 on 2019-06-23 07:57
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('preferences', '0013_auto_20190622_2334'),
]
operations = [
migrations.AlterModelOptions(
name='cotisation',
options={'permissions': (('can_divide', 'Can divide money for cotisation'),)},
),
]

30
preferences/migrations/0015_dividehistory.py

@ -0,0 +1,30 @@
# Generated by Django 2.1 on 2019-06-23 08:49
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('preferences', '0014_auto_20190623_0957'),
]
operations = [
migrations.CreateModel(
name='DivideHistory',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date', models.DateTimeField(auto_now_add=True)),
('total_cotisations', models.IntegerField(verbose_name='Nombre de cotisations')),
('total_cotisations_amount', models.DecimalField(decimal_places=2, max_digits=5, verbose_name='Montant total des cotisations')),
('total_ptm_amount', models.DecimalField(decimal_places=2, max_digits=5, verbose_name='Montant donné au Phœnix Technopôle Metz')),
('coopeman', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='divide_realized', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Historique répartition',
},
),
]

39
preferences/models.py

@ -1,6 +1,7 @@
from django.db import models from django.db import models
from simple_history.models import HistoricalRecords from simple_history.models import HistoricalRecords
from django.core.validators import MinValueValidator from django.core.validators import MinValueValidator
from django.contrib.auth.models import User
class PaymentMethod(models.Model): class PaymentMethod(models.Model):
@ -118,6 +119,8 @@ class Cotisation(models.Model):
""" """
Stores cotisations. Stores cotisations.
""" """
class Meta:
permissions = (("can_divide", "Can divide money for cotisation"),)
amount = models.DecimalField(max_digits=5, decimal_places=2, null=True, verbose_name="Montant", validators=[MinValueValidator(0)]) amount = models.DecimalField(max_digits=5, decimal_places=2, null=True, verbose_name="Montant", validators=[MinValueValidator(0)])
""" """
Price of the cotisation. Price of the cotisation.
@ -126,6 +129,10 @@ class Cotisation(models.Model):
""" """
Duration (in days) of the cotisation Duration (in days) of the cotisation
""" """
amount_ptm = models.DecimalField(max_digits=5, decimal_places=2, null=True, verbose_name="Montant pour le club Phœnix Technopôle Metz")
"""
Amount of money given to the PTM club
"""
history = HistoricalRecords() history = HistoricalRecords()
def __str__(self): def __str__(self):
@ -134,3 +141,35 @@ class Cotisation(models.Model):
else: else:
jour = "jours" jour = "jours"
return "Cotisation de " + str(self.duration) + " " + jour + " pour le prix de " + str(self.amount) + "" return "Cotisation de " + str(self.duration) + " " + jour + " pour le prix de " + str(self.amount) + ""
class DivideHistory(models.Model):
"""
Stores divide history
"""
class Meta:
verbose_name = "Historique répartition"
date = models.DateTimeField(auto_now_add=True)
"""
Date of the divide
"""
total_cotisations = models.IntegerField(verbose_name="Nombre de cotisations")
"""
Number of non-divided cotisations (before the divide)
"""
total_cotisations_amount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Montant total des cotisations")
"""
Amount of non-divided cotisations (before the divide)
"""
total_ptm_amount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Montant donné au Phœnix Technopôle Metz")
"""
Amount given to the PTM
"""
coopeman = models.ForeignKey(User, on_delete=models.PROTECT, related_name="divide_realized")
"""
Coopeman (:class:`django.contrib.auth.models.User`) who collected the reload.
"""
def __str__(self):
return "Répartition du " + str(self.date)

2
preferences/templates/preferences/cotisations_index.html

@ -19,6 +19,7 @@
<tr> <tr>
<th>Durée de cotisation</th> <th>Durée de cotisation</th>
<th>Prix</th> <th>Prix</th>
<th>Pour PhœnixTM</th>
<th>Administration</th> <th>Administration</th>
</tr> </tr>
</thead> </thead>
@ -27,6 +28,7 @@
<tr> <tr>
<td>{{ cotisation.duration }} jour{{ cotisation.duration|pluralize }}</td> <td>{{ cotisation.duration }} jour{{ cotisation.duration|pluralize }}</td>
<td>{{ cotisation.amount }} €</td> <td>{{ cotisation.amount }} €</td>
<td>{{ cotisation.amount_ptm | default:0}} €</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> <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> </tr>
{% endfor %} {% endfor %}

9
templates/nav.html

@ -32,9 +32,14 @@
{% if request.user.is_staff %} {% if request.user.is_staff %}
<span class="tabulation2"> <span class="tabulation2">
<i class="fa fa-chart-bar"></i> <a href="{% url 'gestion:stats' %}">Stats</a> <i class="fa fa-chart-bar"></i> <a href="{% url 'gestion:stats' %}">Stats</a>
</span> </span>
<span class="tabulation2">
<i class="fa fa-business-time"></i> <a href="{% url 'gestion:gen_releve' %}">Relevé</a>
</span>
{% endif %}
{% if perms.preferences.can_divide %}
<span class="tabulation2"> <span class="tabulation2">
<i class="fa fa-business-time"></i> <a href="{% url 'gestion:gen_releve' %}">Comptabilité</a> <i class="fa fa-hand-holding-usd"></i> <a href="{% url 'gestion:divide' %}">Répartition</a>
</span> </span>
{% endif %} {% endif %}
{% if perms.preferences.view_cotisation %} {% if perms.preferences.view_cotisation %}

42
users/migrations/0007_auto_20190623_0957.py

@ -0,0 +1,42 @@
# Generated by Django 2.1 on 2019-06-23 07:57
from django.db import migrations, models
def update(apps, schema_editor):
CotisationHistory = apps.get_model('users', 'CotisationHistory')
for cotisation_history in CotisationHistory.objects.all():
cotisation_history.amount_ptm = cotisation_history.cotisation.amount_ptm
cotisation_history.save()
def reverse_update(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
('users', '0006_auto_20190611_0105'),
]
operations = [
migrations.AddField(
model_name='cotisationhistory',
name='amount_ptm',
field=models.DecimalField(decimal_places=2, max_digits=5, null=True, verbose_name='Montant pour le club Phœnix Technopôle Metz'),
),
migrations.AddField(
model_name='cotisationhistory',
name='divided',
field=models.BooleanField(default=False, verbose_name='Répartition'),
),
migrations.AddField(
model_name='historicalcotisationhistory',
name='amount_ptm',
field=models.DecimalField(decimal_places=2, max_digits=5, null=True, verbose_name='Montant pour le club Phœnix Technopôle Metz'),
),
migrations.AddField(
model_name='historicalcotisationhistory',
name='divided',
field=models.BooleanField(default=False, verbose_name='Répartition'),
),
migrations.RunPython(update, reverse_update)
]

8
users/models.py

@ -61,6 +61,14 @@ class CotisationHistory(models.Model):
""" """
User (:class:`django.contrib.auth.models.User`) who registered the cotisation. User (:class:`django.contrib.auth.models.User`) who registered the cotisation.
""" """
divided = models.BooleanField(default=False, verbose_name="Répartition")
"""
True if money of cotisation have been divided between CTM and PTM
"""
amount_ptm = models.DecimalField(max_digits=5, decimal_places=2, null=True, verbose_name="Montant pour le club Phœnix Technopôle Metz")
"""
Amount of money given to the PTM club
"""
history = HistoricalRecords() history = HistoricalRecords()
class WhiteListHistory(models.Model): class WhiteListHistory(models.Model):

1
users/views.py

@ -583,6 +583,7 @@ def addCotisationHistory(request, pk):
cotisation.coopeman = request.user cotisation.coopeman = request.user
cotisation.amount = cotisation.cotisation.amount cotisation.amount = cotisation.cotisation.amount
cotisation.duration = cotisation.cotisation.duration cotisation.duration = cotisation.cotisation.duration
cotisation.amount_ptm = cotisation.cotisation.amount_ptm
if(user.profile.cotisationEnd and user.profile.cotisationEnd > timezone.now()): if(user.profile.cotisationEnd and user.profile.cotisationEnd > timezone.now()):
cotisation.endDate = user.profile.cotisationEnd + timedelta(days=cotisation.cotisation.duration) cotisation.endDate = user.profile.cotisationEnd + timedelta(days=cotisation.cotisation.duration)
else: else:

Loading…
Cancel
Save