3
0
Fork 0
mirror of https://github.com/nanoy42/coope synced 2024-12-24 16:03:47 +00:00

Gestion des f^uts

This commit is contained in:
Yoann Pétri 2018-11-25 13:52:32 +01:00
parent ca6c938e20
commit a45d7746f5
16 changed files with 426 additions and 26 deletions

View file

@ -1,9 +1,11 @@
from django.contrib import admin from django.contrib import admin
from .models import Reload, Refund, Product, Keg, ConsumptionHistory from .models import Reload, Refund, Product, Keg, ConsumptionHistory, KegHistory, Consumption
admin.site.register(Reload) admin.site.register(Reload)
admin.site.register(Refund) admin.site.register(Refund)
admin.site.register(Product) admin.site.register(Product)
admin.site.register(Keg) admin.site.register(Keg)
admin.site.register(ConsumptionHistory) admin.site.register(ConsumptionHistory)
admin.site.register(KegHistory)
admin.site.register(Consumption)

View file

@ -65,3 +65,9 @@ class SearchMenuForm(forms.Form):
class GestionForm(forms.Form): class GestionForm(forms.Form):
client = forms.ModelChoiceField(queryset=User.objects.filter(is_active=True), required=True, label="Client", widget=autocomplete.ModelSelect2(url='users:active-users-autocomplete', attrs={'data-minimum-input-length':2})) client = forms.ModelChoiceField(queryset=User.objects.filter(is_active=True), required=True, label="Client", widget=autocomplete.ModelSelect2(url='users:active-users-autocomplete', attrs={'data-minimum-input-length':2}))
class SelectPositiveKegForm(forms.Form):
keg = forms.ModelChoiceField(queryset=Keg.objects.filter(stockHold__gt = 0), required=True, label="Fût", widget=autocomplete.ModelSelect2(url='gestion:kegs-positive-autocomplete'))
class SelectActiveKegForm(forms.Form):
keg = forms.ModelChoiceField(queryset=Keg.objects.filter(is_active = True), required=True, label="Fût", widget=autocomplete.ModelSelect2(url='gestion:kegs-active-autocomplete'))

View file

@ -0,0 +1,33 @@
# Generated by Django 2.1 on 2018-11-23 01:29
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gestion', '0001_initial'),
]
operations = [
migrations.RenameField(
model_name='keghistory',
old_name='Keg',
new_name='keg',
),
migrations.AlterField(
model_name='keghistory',
name='amountSold',
field=models.DecimalField(decimal_places=2, default=0, max_digits=5),
),
migrations.AlterField(
model_name='keghistory',
name='closingDate',
field=models.DateTimeField(blank=True, null=True),
),
migrations.AlterField(
model_name='keghistory',
name='quantitySold',
field=models.DecimalField(decimal_places=2, default=0, max_digits=5),
),
]

View file

@ -0,0 +1,22 @@
# Generated by Django 2.1 on 2018-11-23 02:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gestion', '0002_auto_20181123_0229'),
]
operations = [
migrations.AlterModelOptions(
name='keg',
options={'permissions': (('open_keg', 'Peut percuter les fûts'), ('close_keg', 'Peut fermer les fûts'))},
),
migrations.AddField(
model_name='product',
name='adherentRequired',
field=models.BooleanField(default=True),
),
]

View file

@ -0,0 +1,25 @@
# Generated by Django 2.1 on 2018-11-23 13:03
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),
('gestion', '0003_auto_20181123_0330'),
]
operations = [
migrations.CreateModel(
name='Consumption',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('quantity', models.PositiveIntegerField(default=0)),
('customer', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='consumption_global_taken', to=settings.AUTH_USER_MODEL)),
('product', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='gestion.Product')),
],
),
]

View file

@ -30,6 +30,7 @@ class Product(models.Model):
is_active = models.BooleanField(default=True, verbose_name="Actif") is_active = models.BooleanField(default=True, verbose_name="Actif")
volume = models.IntegerField(default=0) volume = models.IntegerField(default=0)
deg = models.DecimalField(default=0,max_digits=5, decimal_places=2, verbose_name="Degré") deg = models.DecimalField(default=0,max_digits=5, decimal_places=2, verbose_name="Degré")
adherentRequired = models.BooleanField(default=True)
def __str__(self): def __str__(self):
return self.name return self.name
@ -61,6 +62,12 @@ def isGalopin(id):
) )
class Keg(models.Model): class Keg(models.Model):
class Meta:
permissions = (
("open_keg", "Peut percuter les fûts"),
("close_keg", "Peut fermer les fûts")
)
name = models.CharField(max_length=20, unique=True, verbose_name="Nom") name = models.CharField(max_length=20, unique=True, verbose_name="Nom")
stockHold = models.IntegerField(default=0, verbose_name="Stock en soute") stockHold = models.IntegerField(default=0, verbose_name="Stock en soute")
barcode = models.CharField(max_length=20, unique=True, verbose_name="Code barre") barcode = models.CharField(max_length=20, unique=True, verbose_name="Code barre")
@ -75,13 +82,21 @@ class Keg(models.Model):
return self.name return self.name
class KegHistory(models.Model): class KegHistory(models.Model):
Keg = models.ForeignKey(Keg, on_delete=models.PROTECT) keg = models.ForeignKey(Keg, on_delete=models.PROTECT)
openingDate = models.DateTimeField(auto_now_add=True) openingDate = models.DateTimeField(auto_now_add=True)
quantitySold = models.DecimalField(decimal_places=2, max_digits=5) quantitySold = models.DecimalField(decimal_places=2, max_digits=5, default=0)
amountSold = models.DecimalField(decimal_places=2, max_digits=5) amountSold = models.DecimalField(decimal_places=2, max_digits=5, default=0)
closingDate = models.DateTimeField() closingDate = models.DateTimeField(null=True, blank=True)
isCurrentKegHistory = models.BooleanField(default=True) isCurrentKegHistory = models.BooleanField(default=True)
def __str__(self):
res = "Fût de " + str(self.keg) + " (" + str(self.openingDate) + " - "
if(self.closingDate):
res += str(self.closingDate) + ")"
else:
res += "?)"
return res
class Reload(models.Model): class Reload(models.Model):
customer = models.ForeignKey(User, on_delete=models.PROTECT, related_name="reload_taken", verbose_name="Client") customer = models.ForeignKey(User, on_delete=models.PROTECT, related_name="reload_taken", verbose_name="Client")
amount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Montant") amount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Montant")
@ -152,3 +167,11 @@ class ConsumptionHistory(models.Model):
def __str__(self): def __str__(self):
return "{0} {1} consommé par {2} le {3} (encaissé par {4})".format(self.quantity, self.product, self.customer, self.date, self.coopeman) return "{0} {1} consommé par {2} le {3} (encaissé par {4})".format(self.quantity, self.product, self.customer, self.date, self.coopeman)
class Consumption(models.Model):
customer = models.ForeignKey(User, on_delete=models.PROTECT, related_name="consumption_global_taken")
product = models.ForeignKey(Product, on_delete=models.PROTECT)
quantity = models.PositiveIntegerField(default=0)
def __str__(self):
return "Consommation de " + str(self.customer) + " concernant le produit " + str(self.product)

View file

@ -0,0 +1,21 @@
{% extends 'base.html' %}
{% block entete %}<h1>Gestion des produits</h1>{% endblock %}
{% block navbar%}
<ul>
<li><a href="#first">Historique du fût</a></li>
</ul>
{% endblock %}
{% block content %}
<section id="first" class="main">
<header class="major">
<h2>Historique du fût {{ keg.name }}</h2>
</header>
<a href="{% url 'gestion:kegsList' %}">Retour à la liste des fûts</a><br><br>
{% for kegH in kegHistory %}
<h2>Du {{kegH.openingDate}} au {{kegH.closingDate | default:"?"}}</h2>
Quantité vendue : {{ kegH.quantitySold }} L<br>
Montant vendu : {{ kegH.amountSold }} €(prix fût : {{keg.amount}} €)<br><br>
{% endfor %}
</section>
{% endblock %}

View file

@ -0,0 +1,89 @@
{% extends 'base.html' %}
{% block entete %}<h1>Gestion des produits</h1>{% endblock %}
{% block navbar%}
<ul>
<li><a href="#first">Liste des fûts actifs</a></li>
<li><a href="#second">Liste des fûts inactifs</a></li>
</ul>
{% endblock %}
{% block content %}
<section id="first" class="main">
<header class="major">
<h2>Liste des fûts actifs</h2>
</header>
<a class="button" href="{% url 'gestion:addKeg' %}">Créer un fût</a>
<a class="button" href="{% url 'gestion:openKeg' %}">Percuter un fût</a>
<a class="button" href="{% url 'gestion:closeKeg' %}">Fermer un fût</a>
<br><br>
<div class="table-wrapper">
<table>
<thead>
<tr>
<th>Nom</th>
<th>Stock en soute</th>
<th>Code barre</th>
<th>Capacité</th>
<th>Quantité vendue</th>
<th>Montant vendu</th>
<th>Prix du fût</th>
<th>Historique</th>
<th>Administrer</th>
</tr>
</thead>
<tbody>
{% for kegH in kegs_active %}
<tr>
<td>{{ kegH.keg.name }}</td>
<td>{{ kegH.keg.stockHold}}</td>
<td>{{ kegH.keg.barcode }}</td>
<td>{{ kegH.keg.capacity }} L</td>
<td>{{ kegH.quantitySold }} L</td>
<td>{{ kegH.amountSold }} €</td>
<td>{{ kegH.keg.amount }} €</td>
<td><a href="{% url 'gestion:kegH' kegH.keg.pk %}">Voir</a></td>
<td><a href="{% url 'gestion:closeDirectKeg' kegH.keg.pk %}" class="button small">Fermer</a> <a href="{% url 'gestion:editKeg' kegH.keg.pk %}" class="button small">Modifier</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</section>
<section id="first" class="main">
<header class="major">
<h2>Liste des fûts inactifs</h2>
</header>
<a class="button" href="{% url 'gestion:addKeg' %}">Créer un fût</a>
<a class="button" href="{% url 'gestion:openKeg' %}">Percuter un fût</a>
<a class="button" href="{% url 'gestion:closeKeg' %}">Fermer un fût</a>
<br><br>
<div class="table-wrapper">
<table>
<thead>
<tr>
<th>Nom</th>
<th>Stock en soute</th>
<th>Code barre</th>
<th>Capacité</th>
<th>Prix du fût</th>
<th>Historique</th>
<th>Administrer</th>
</tr>
</thead>
<tbody>
{% for keg in kegs_inactive %}
<tr>
<td>{{ keg.name }}</td>
<td>{{ keg.stockHold}}</td>
<td>{{ keg.barcode }}</td>
<td>{{ keg.capacity }} L</td>
<td>{{ keg.amount }} €</td>
<td><a href="{% url 'gestion:kegH' keg.pk %}">Voir</a></td>
<td>{% if keg.stockHold > 0 %}<a href="{% url 'gestion:openDirectKeg' keg.pk %}" class="button small">Percuter</a>{% endif %} <a href="{% url 'gestion:editKeg' keg.pk %}" class="button small">Modifier</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</section>
{% endblock %}

View file

@ -27,9 +27,9 @@
Actions possibles : Actions possibles :
<ul> <ul>
<li><a href="{% url 'gestion:addKeg' %}">Créer un fut</a></li> <li><a href="{% url 'gestion:addKeg' %}">Créer un fut</a></li>
<li><a href="">Percuter un fut</a></li> <li><a href="{% url 'gestion:openKeg' %}">Percuter un fut</a></li>
<li><a href="">Lister les futs</a></li> <li><a href="{% url 'gestion:closeKeg' %}">Fermer un fût</a></li>
<li><a href="">Historique des futs</a></li> <li><a href="{% url 'gestion:kegsList' %}">Lister les futs</a></li>
</ul> </ul>
</section> </section>
<section id="third" class="main"> <section id="third" class="main">

View file

@ -2,10 +2,7 @@
{% block entete %}<h1>Gestion des produits</h1>{% endblock %} {% block entete %}<h1>Gestion des produits</h1>{% endblock %}
{% block navbar%} {% block navbar%}
<ul> <ul>
<li><a href="#first">Produits</a></li> <li><a href="#first">Liste des produits</a></li>
<li><a href="#second">Futs</a></li>
<li><a href="#third">Menus</a></li>
<li><a href="#fourth">Stocks</a></li>
</ul> </ul>
{% endblock %} {% endblock %}
{% block content %} {% block content %}

View file

@ -11,6 +11,13 @@ urlpatterns = [
path('productsList', views.productsList, name="productsList"), path('productsList', views.productsList, name="productsList"),
path('addProduct', views.addProduct, name="addProduct"), path('addProduct', views.addProduct, name="addProduct"),
path('addKeg', views.addKeg, name="addKeg"), path('addKeg', views.addKeg, name="addKeg"),
path('openKeg', views.openKeg, name="openKeg"),
path('closeKeg', views.closeKeg, name="closeKeg"),
path('kegsList', views.kegsList, name="kegsList"),
path('kegH/<int:pk>', views.kegH, name="kegH"),
path('editKeg/<int:pk>', views.editKeg, name="editKeg"),
path('openDirectKeg/<int:pk>', views.openDirectKeg, name="openDirectKeg"),
path('closeDirectKeg/<int:pk>', views.closeDirectKeg, name="closeDirectKeg"),
path('addMenu', views.addMenu, name="addMenu"), path('addMenu', views.addMenu, name="addMenu"),
path('getProduct/<str:barcode>', views.getProduct, name="getProduct"), path('getProduct/<str:barcode>', views.getProduct, name="getProduct"),
path('order', views.order, name="order"), path('order', views.order, name="order"),
@ -19,4 +26,7 @@ urlpatterns = [
path('searchProduct', views.searchProduct, name="searchProduct"), path('searchProduct', views.searchProduct, name="searchProduct"),
path('productProfile/<int:pk>', views.productProfile, name="productProfile"), path('productProfile/<int:pk>', views.productProfile, name="productProfile"),
path('products-autocomplete', views.ProductsAutocomplete.as_view(), name="products-autocomplete"), path('products-autocomplete', views.ProductsAutocomplete.as_view(), name="products-autocomplete"),
path('kegs-positive-autocomplete', views.KegPositiveAutocomplete.as_view(), name="kegs-positive-autocomplete"),
path('kegs-active-autocomplete', views.KegActiveAutocomplete.as_view(), name="kegs-active-autocomplete"),
] ]

View file

@ -5,6 +5,7 @@ from django.http import HttpResponse, Http404
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.decorators import login_required, permission_required
from django.utils import timezone
from coopeV3.acl import active_required, acl_or from coopeV3.acl import active_required, acl_or
@ -12,8 +13,8 @@ import simplejson as json
from dal import autocomplete from dal import autocomplete
from decimal import * from decimal import *
from .forms import ReloadForm, RefundForm, ProductForm, KegForm, MenuForm, GestionForm, SearchMenuForm, SearchProductForm from .forms import ReloadForm, RefundForm, ProductForm, KegForm, MenuForm, GestionForm, SearchMenuForm, SearchProductForm, SelectPositiveKegForm, SelectActiveKegForm
from .models import Product, Menu, Keg, ConsumptionHistory from .models import Product, Menu, Keg, ConsumptionHistory, KegHistory, Consumption
from preferences.models import PaymentMethod from preferences.models import PaymentMethod
@active_required @active_required
@ -44,26 +45,62 @@ def manage(request):
@permission_required('gestion.add_consumptionhistory') @permission_required('gestion.add_consumptionhistory')
@csrf_exempt @csrf_exempt
def order(request): def order(request):
print(request.POST)
if("user" not in request.POST or "paymentMethod" not in request.POST or "amount" not in request.POST or "order" not in request.POST): if("user" not in request.POST or "paymentMethod" not in request.POST or "amount" not in request.POST or "order" not in request.POST):
raise Http404("Erreur du POST") return HttpResponse("Erreur du POST")
else: else:
user = get_object_or_404(User, pk=request.POST['user']) user = get_object_or_404(User, pk=request.POST['user'])
paymentMethod = get_object_or_404(PaymentMethod, pk=request.POST['paymentMethod']) paymentMethod = get_object_or_404(PaymentMethod, pk=request.POST['paymentMethod'])
amount = Decimal(request.POST['amount']) amount = Decimal(request.POST['amount'])
order = json.loads(request.POST["order"]) order = json.loads(request.POST["order"])
if(len(order) == 0 or amount == 0): if(len(order) == 0 or amount == 0):
raise Http404("Pas de commande") return HttpResponse("Pas de commande")
adherentRequired = False
for o in order:
product = get_object_or_404(Product, pk=o["pk"])
adherentRequired = adherentRequired or product.adherentRequired
if(adherentRequired and not user.profile.is_adherent):
return HttpResponse("N'est pas adhérent et devrait l'être")
if(paymentMethod.affect_balance): if(paymentMethod.affect_balance):
if(user.profile.balance < amount): if(user.profile.balance < amount):
raise Http404("Solde inférieur au prix de la commande") return HttpResponse("Solde inférieur au prix de la commande")
else: else:
user.profile.debit += amount user.profile.debit += amount
user.save() user.save()
for o in order: for o in order:
print(o)
product = get_object_or_404(Product, pk=o["pk"]) product = get_object_or_404(Product, pk=o["pk"])
ch = ConsumptionHistory(customer = user, quantity = int(o["quantity"]), paymentMethod=paymentMethod, product=product, amount=int(o["quantity"])*product.amount, coopeman=request.user) quantity = int(o["quantity"])
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")
kegHistory = get_object_or_404(KegHistory, keg=keg, isCurrentKegHistory=True)
kegHistory.quantitySold += Decimal(quantity * 0.5)
kegHistory.amountSold += Decimal(quantity * product.amount)
kegHistory.save()
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")
kegHistory = get_object_or_404(KegHistory, keg=keg, isCurrentKegHistory=True)
kegHistory.quantitySold += Decimal(quantity * 0.25)
kegHistory.amountSold += Decimal(quantity * product.amount)
kegHistory.save()
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")
kegHistory = get_object_or_404(KegHistory, keg=keg, isCurrentKegHistory=True)
kegHistory.quantitySold += Decimal(quantity * 0.125)
kegHistory.amountSold += Decimal(quantity * product.amount)
kegHistory.save()
else:
if(product.stockHold > 0):
product.stockHold -= 1
product.save()
consumption, _ = Consumption.objects.get_or_create(customer=user, product=product)
consumption.quantity += quantity
consumption.save()
ch = ConsumptionHistory(customer = user, quantity = quantity, paymentMethod=paymentMethod, product=product, amount=int(o["quantity"])*product.amount, coopeman=request.user)
ch.save() ch.save()
return HttpResponse("La commande a bien été effectuée") return HttpResponse("La commande a bien été effectuée")
@ -163,9 +200,120 @@ def addKeg(request):
if(form.is_valid()): if(form.is_valid()):
keg = form.save() keg = form.save()
messages.success(request, "Le fût " + keg.name + " a bien été ajouté") messages.success(request, "Le fût " + keg.name + " a bien été ajouté")
return redirect(reverse('gestion:productsIndex')) 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"})
@login_required
@permission_required('gestion.edit_keg')
def editKeg(request, pk):
keg = get_object_or_404(Keg, pk=pk)
form = KegForm(request.POST or None, instance=keg)
if(form.is_valid()):
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"})
@login_required
@permission_required('gestion.open_keg')
def openKeg(request):
form = SelectPositiveKegForm(request.POST or None)
if(form.is_valid()):
keg = form.cleaned_data['keg']
previousKegHistory = KegHistory.objects.filter(keg=keg).filter(isCurrentKegHistory=True)
for pkh in previousKegHistory:
pkh.isCurrentKegHistory = False
pkh.closingDate = timezone.now()
pkh.save()
kegHistory = KegHistory(keg = keg)
kegHistory.save()
keg.stockHold -= 1
keg.is_active = True
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"})
@login_required
@permission_required('gestion.open_keg')
def openDirectKeg(request, pk):
keg = get_object_or_404(Keg, pk=pk)
if(keg.stockHold > 0):
previousKegHistory = KegHistory.objects.filter(keg=keg).filter(isCurrentKegHistory=True)
for pkh in previousKegHistory:
pkh.isCurrentKegHistory = False
pkh.closingDate = timezone.now()
pkh.save()
kegHistory = KegHistory(keg = keg)
kegHistory.save()
keg.stockHold -= 1
keg.is_active = True
keg.save()
messages.success(request, "Le fût a bien été percuté")
else:
messages.error(request, "Il n'y a pas de fût en stock")
return redirect(reverse('gestion:kegsList'))
@login_required
@permission_required('gestion.close_keg')
def closeKeg(request):
form = SelectActiveKegForm(request.POST or None)
if(form.is_valid()):
keg = form.cleaned_data['keg']
kegHistory = get_object_or_404(KegHistory, keg=keg, isCurrentKegHistory=True)
kegHistory.isCurrentKegHistory = False
kegHistory.closingDate = timezone.now()
kegHistory.save()
keg.is_active = False
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"})
@login_required
@permission_required('gestion:close_keg')
def closeDirectKeg(request, pk):
keg = get_object_or_404(Keg, pk=pk)
if(keg.is_active):
kegHistory = get_object_or_404(KegHistory, keg=keg, isCurrentKegHistory=True)
kegHistory.isCurrentKegHistory = False
kegHistory.closingDate = timezone.now()
kegHistory.save()
keg.is_active = False
keg.save()
messages.success(request, "Le fût a bien été fermé")
else:
messages.error(request, "Le fût n'est pas ouvert")
return redirect(reverse('gestion:kegsList'))
@login_required
@permission_required('gestion.view_keg')
def kegsList(request):
kegs_active = KegHistory.objects.filter(isCurrentKegHistory=True)
ids_actives = kegs_active.values('id')
kegs_inactive = Keg.objects.exclude(id__in = ids_actives)
return render(request, "gestion/kegs_list.html", {"kegs_active": kegs_active, "kegs_inactive": kegs_inactive})
@login_required
@permission_required('gestion.view_keghistory')
def kegH(request, pk):
keg = get_object_or_404(Keg, pk=pk)
kegHistory = KegHistory.objects.filter(keg=keg).order_by('-openingDate')
return render(request, "gestion/kegh.html", {"keg": keg, "kegHistory": kegHistory})
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)
return qs
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)
return qs
########## Menus ########## ########## Menus ##########

View file

@ -74,6 +74,5 @@ $(document).ready(function(){
alert("Impossible d'effectuer la transaction"); alert("Impossible d'effectuer la transaction");
location.reload(); location.reload();
}); });
}); });
}); });

View file

@ -0,0 +1,17 @@
# Generated by Django 2.1 on 2018-11-23 01:29
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('users', '0002_auto_20181009_1119'),
]
operations = [
migrations.AlterModelOptions(
name='cotisationhistory',
options={'permissions': (('validate_consumptionhistory', 'Peut (in)valider les cotisations'),)},
),
]

View file

@ -2,6 +2,7 @@ from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.dispatch import receiver from django.dispatch import receiver
from django.utils import timezone
from preferences.models import PaymentMethod, Cotisation from preferences.models import PaymentMethod, Cotisation
from gestion.models import ConsumptionHistory from gestion.models import ConsumptionHistory
@ -50,6 +51,13 @@ class Profile(models.Model):
school = models.ForeignKey(School, on_delete=models.PROTECT, blank=True, null=True) school = models.ForeignKey(School, on_delete=models.PROTECT, blank=True, null=True)
cotisationEnd = models.DateTimeField(blank=True, null=True) cotisationEnd = models.DateTimeField(blank=True, null=True)
@property
def is_adherent(self):
if(self.cotisationEnd and self.cotisationEnd > timezone.now()):
return True
else:
return False
@property @property
def balance(self): def balance(self):
return self.credit - self.debit return self.credit - self.debit

View file

@ -627,8 +627,8 @@ def addCotisationHistory(request, pk):
if(form.is_valid()): if(form.is_valid()):
cotisation = form.save(commit=False) cotisation = form.save(commit=False)
if(cotisation.paymentMethod.affect_balance): if(cotisation.paymentMethod.affect_balance):
if(user.profile.balance >= cotisation.amount): if(user.profile.balance >= cotisation.cotisation.amount):
user.profile.balance -= cotisation.amount user.profile.debit += cotisation.cotisation.amount
else: else:
cotisation.delete() cotisation.delete()
messages.error(request, "Solde insuffisant") messages.error(request, "Solde insuffisant")