Browse Source

Merge pull request #18 from nanoy42/dev

Dev
pull/21/head v3.6.4
Yoann Pietri 6 years ago
committed by GitHub
parent
commit
d7e21b6600
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      CHANGELOG.md
  2. 4
      gestion/admin.py
  3. 23
      gestion/forms.py
  4. 23
      gestion/migrations/0013_auto_20190829_1219.py
  5. 8
      gestion/models.py
  6. 1
      gestion/templates/gestion/product_profile.html
  7. 2
      gestion/templates/gestion/stocks.html
  8. 72
      gestion/views.py
  9. 2
      templates/footer.html

3
CHANGELOG.md

@ -1,3 +1,6 @@
## v3.6.4
* Ajout d'un champ use_stocks
* Séparation des formulaires de fût
## v3.6.3 ## v3.6.3
* Refonte totale du système de stocks * Refonte totale du système de stocks
* Fix price profile * Fix price profile

4
gestion/admin.py

@ -59,10 +59,10 @@ class ProductAdmin(SimpleHistoryAdmin):
""" """
The admin class for :class:`Products <gestion.models.Product>`. The admin class for :class:`Products <gestion.models.Product>`.
""" """
list_display = ('name', 'amount', 'is_active', 'category', 'adherentRequired', 'stock', 'volume', 'deg') list_display = ('name', 'amount', 'is_active', 'category', 'adherentRequired', 'stock', 'volume', 'deg', 'use_stocks')
ordering = ('name', 'amount', 'stock', 'deg') ordering = ('name', 'amount', 'stock', 'deg')
search_fields = ('name',) search_fields = ('name',)
list_filter = ('is_active', 'adherentRequired', 'category') list_filter = ('is_active', 'adherentRequired', 'category', 'use_stocks')
class ReloadAdmin(SimpleHistoryAdmin): class ReloadAdmin(SimpleHistoryAdmin):
""" """

23
gestion/forms.py

@ -42,9 +42,9 @@ class ProductForm(forms.ModelForm):
fields = "__all__" fields = "__all__"
widgets = {'amount': forms.TextInput} widgets = {'amount': forms.TextInput}
class KegForm(forms.ModelForm): class CreateKegForm(forms.ModelForm):
""" """
A form to create and edit a :class:`~gestion.models.Keg`. A form to create a :class:`~gestion.models.Keg`.
""" """
class Meta: class Meta:
@ -52,9 +52,24 @@ class KegForm(forms.ModelForm):
fields = ["name", "stockHold", "amount", "capacity"] fields = ["name", "stockHold", "amount", "capacity"]
widgets = {'amount': forms.TextInput} widgets = {'amount': forms.TextInput}
category = forms.ModelChoiceField(queryset=Category.objects.all(), label="Catégorie") category = forms.ModelChoiceField(queryset=Category.objects.all(), label="Catégorie", help_text="Catégorie dans laquelle placer les produits pinte, demi (et galopin si besoin).")
deg = forms.DecimalField(max_digits=5, decimal_places=2, label="Degré", validators=[MinValueValidator(0)]) deg = forms.DecimalField(max_digits=5, decimal_places=2, label="Degré", validators=[MinValueValidator(0)])
create_galopin = forms.BooleanField(label="Créer le produit galopin ?") create_galopin = forms.BooleanField(required=False, label="Créer le produit galopin ?")
def clean(self):
cleaned_data = super().clean()
if cleaned_data.get("name")[0:4] != "Fût ":
raise ValidationError("Le nom du fût doit être sous la forme 'Fût nom de la bière'")
class EditKegForm(forms.ModelForm):
"""
A form to edit a :class:`~gestion.models.Keg`.
"""
class Meta:
model = Keg
fields = ["name", "stockHold", "amount", "capacity", "pinte", "demi", "galopin"]
widgets = {'amount': forms.TextInput}
def clean(self): def clean(self):
cleaned_data = super().clean() cleaned_data = super().clean()

23
gestion/migrations/0013_auto_20190829_1219.py

@ -0,0 +1,23 @@
# Generated by Django 2.1 on 2019-08-29 10:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gestion', '0012_auto_20190827_2119'),
]
operations = [
migrations.AddField(
model_name='historicalproduct',
name='use_stocks',
field=models.BooleanField(default=True, verbose_name='Utiliser les stocks ?'),
),
migrations.AddField(
model_name='product',
name='use_stocks',
field=models.BooleanField(default=True, verbose_name='Utiliser les stocks ?'),
),
]

8
gestion/models.py

@ -27,6 +27,13 @@ class Category(models.Model):
""" """
return self.product_set.filter(is_active=True) return self.product_set.filter(is_active=True)
@property
def active_stock_products(self):
"""
Return active products that use stocks
"""
return self.product_set.filter(is_active=True).filter(use_stocks=True)
class Product(models.Model): class Product(models.Model):
""" """
Stores a product. Stores a product.
@ -87,6 +94,7 @@ class Product(models.Model):
On the graphs on :func:`users.views.profile` view, the number of total consumptions is divised by the showingMultiplier On the graphs on :func:`users.views.profile` view, the number of total consumptions is divised by the showingMultiplier
""" """
draft_category = models.IntegerField(choices=DRAFT_TYPES, default=DRAFT_NONE, verbose_name="Type de pression") draft_category = models.IntegerField(choices=DRAFT_TYPES, default=DRAFT_NONE, verbose_name="Type de pression")
use_stocks = models.BooleanField(default=True, verbose_name="Utiliser les stocks ?")
history = HistoricalRecords() history = HistoricalRecords()
def __str__(self): def __str__(self):

1
gestion/templates/gestion/product_profile.html

@ -19,5 +19,6 @@
<strong>Actif</strong> : {{ product.is_active | yesno:"Oui, Non"}}<br> <strong>Actif</strong> : {{ product.is_active | yesno:"Oui, Non"}}<br>
<strong>Dégré</strong> : {{ product.deg }}<br> <strong>Dégré</strong> : {{ product.deg }}<br>
<strong>Volume</strong> : {{ product.volume }}cl<br> <strong>Volume</strong> : {{ product.volume }}cl<br>
<strong>Utiliser les stocks</strong> : {{product.use_stocks|yesno:"Oui,Non"}}<br>
</section> </section>
{% endblock %} {% endblock %}

2
gestion/templates/gestion/stocks.html

@ -24,7 +24,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for product in category.active_products %} {% for product in category.active_stock_products %}
<tr id="tr-{{product.pk}}"> <tr id="tr-{{product.pk}}">
<td><a href="{% url 'gestion:productProfile' product.pk %}">{{ product.name }}</a></td> <td><a href="{% url 'gestion:productProfile' product.pk %}">{{ product.name }}</a></td>
<td id="stock-{{product.pk}}">{{ product.stock }}</td> <td id="stock-{{product.pk}}">{{ product.stock }}</td>

72
gestion/views.py

@ -22,7 +22,7 @@ from decimal import *
import os import os
from math import floor, ceil from math import floor, ceil
from .forms import ReloadForm, RefundForm, ProductForm, KegForm, MenuForm, GestionForm, SearchMenuForm, SearchProductForm, SelectPositiveKegForm, SelectActiveKegForm, PinteForm, GenerateReleveForm, CategoryForm, SearchCategoryForm, GenerateInvoiceForm, ComputePriceForm from .forms import ReloadForm, RefundForm, ProductForm, CreateKegForm, EditKegForm, MenuForm, GestionForm, SearchMenuForm, SearchProductForm, SelectPositiveKegForm, SelectActiveKegForm, PinteForm, GenerateReleveForm, CategoryForm, SearchCategoryForm, GenerateInvoiceForm, ComputePriceForm
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, DivideHistory, PriceProfile from preferences.models import PaymentMethod, GeneralPreferences, Cotisation, DivideHistory, PriceProfile
@ -160,7 +160,7 @@ def order(request):
kegHistory.quantitySold += Decimal(quantity * 0.125) kegHistory.quantitySold += Decimal(quantity * 0.125)
kegHistory.amountSold += Decimal(quantity * product.amount) kegHistory.amountSold += Decimal(quantity * product.amount)
kegHistory.save() kegHistory.save()
else: if product.use_stocks:
if(product.stock > quantity): if(product.stock > quantity):
product.stock -= quantity product.stock -= quantity
product.save() product.save()
@ -197,11 +197,36 @@ def order(request):
consumption, _ = Consumption.objects.get_or_create(customer=user, product=article) consumption, _ = Consumption.objects.get_or_create(customer=user, product=article)
consumption.quantity += quantity consumption.quantity += quantity
consumption.save() consumption.save()
if(article.stock > quantity): if(article.draft_category == Product.DRAFT_PINTE):
article.stock -= quantity keg = get_object_or_404(Keg, pinte=article)
article.save() if(not keg.is_active):
else: raise Exception("Fût non actif")
raise Exception("Le stock du produit " + article.name + "n'autorise pas l'opération") 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(article.draft_category == Product.DRAFT_DEMI):
keg = get_object_or_404(Keg, demi=article)
if(not keg.is_active):
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)
kegHistory.save()
elif(article.draft_category == Product.DRAFT_GALOPIN):
keg = get_object_or_404(Keg, galopin=article)
if(not keg.is_active):
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)
kegHistory.save()
if article.use_stocks:
if(article.stock > quantity):
article.stock -= quantity
article.save()
else:
raise Exception("Le stock du produit " + article.name + "n'autorise pas l'opération")
user.profile.alcohol += Decimal(quantity * float(product.deg) * product.volume * 0.79 /10 /1000) user.profile.alcohol += Decimal(quantity * float(product.deg) * product.volume * 0.79 /10 /1000)
user.save() user.save()
return HttpResponse("La commande a bien été effectuée") return HttpResponse("La commande a bien été effectuée")
@ -296,8 +321,9 @@ def cancel_consumption(request, pk):
consumptionT = Consumption.objects.get(customer=user, product=consumption.product) consumptionT = Consumption.objects.get(customer=user, product=consumption.product)
consumptionT.quantity -= consumption.quantity consumptionT.quantity -= consumption.quantity
consumptionT.save() consumptionT.save()
product.stock += consumption.quantity if product.use_stocks:
product.save() product.stock += consumption.quantity
product.save()
consumption.delete() consumption.delete()
messages.success(request, "La consommation a bien été annulée") messages.success(request, "La consommation a bien été annulée")
return redirect(reverse('users:profile', kwargs={'pk': user.pk})) return redirect(reverse('users:profile', kwargs={'pk': user.pk}))
@ -467,8 +493,9 @@ class ActiveProductsAutocomplete(autocomplete.Select2QuerySetView):
def update_stock(request, pk): def update_stock(request, pk):
product = get_object_or_404(Product, pk=pk) product = get_object_or_404(Product, pk=pk)
if("stock" in request.GET): if("stock" in request.GET):
product.stock = request.GET.get("stock") if product.use_stocks:
product.save() product.stock = request.GET.get("stock")
product.save()
return HttpResponse("Le stock a bien été mis à jour") return HttpResponse("Le stock a bien été mis à jour")
@active_required @active_required
@ -488,12 +515,16 @@ def stocks(request):
@permission_required('gestion.add_keg') @permission_required('gestion.add_keg')
def addKeg(request): def addKeg(request):
""" """
Displays a :class:`gestion.forms.KegForm` to add a :class:`gestion.models.Keg`. Displays a :class:`gestion.forms.CreateKegForm` to add a :class:`gestion.models.Keg`.
""" """
form = KegForm(request.POST or None) form = CreateKegForm(request.POST or None)
if form.is_valid(): if form.is_valid():
try:
price_profile = PriceProfile.objects.get(use_for_draft=True)
except:
messages.error(request, "Il n'y a pas de profil de prix pour les pressions")
return redirect(reverse('preferences:priceProfilesIndex'))
keg = form.save(commit=False) keg = form.save(commit=False)
price_profile = get_object_or_404(PriceProfile, use_for_draft=True)
pinte_price = compute_price(form.cleaned_data["amount"]/(2*form.cleaned_data["capacity"]), price_profile.a, price_profile.b, price_profile.c, price_profile.alpha) pinte_price = compute_price(form.cleaned_data["amount"]/(2*form.cleaned_data["capacity"]), price_profile.a, price_profile.b, price_profile.c, price_profile.alpha)
pinte_price = ceil(10*pinte_price)/10 pinte_price = ceil(10*pinte_price)/10
name = form.cleaned_data["name"][4:] name = form.cleaned_data["name"][4:]
@ -509,7 +540,8 @@ def addKeg(request):
deg = form.cleaned_data["deg"], deg = form.cleaned_data["deg"],
adherentRequired = True, adherentRequired = True,
showingMultiplier = 1, showingMultiplier = 1,
draft_category = Product.DRAFT_PINTE draft_category = Product.DRAFT_PINTE,
use_stocks=False,
) )
pinte.save() pinte.save()
keg.pinte = pinte keg.pinte = pinte
@ -524,7 +556,8 @@ def addKeg(request):
deg = form.cleaned_data["deg"], deg = form.cleaned_data["deg"],
adherentRequired = True, adherentRequired = True,
showingMultiplier = 1, showingMultiplier = 1,
draft_category = Product.DRAFT_DEMI draft_category = Product.DRAFT_DEMI,
use_stocks=False,
) )
demi.save() demi.save()
keg.demi = demi keg.demi = demi
@ -540,7 +573,8 @@ def addKeg(request):
deg = form.cleaned_data["deg"], deg = form.cleaned_data["deg"],
adherentRequired = True, adherentRequired = True,
showingMultiplier = 1, showingMultiplier = 1,
draft_category = Product.DRAFT_DEMI draft_category = Product.DRAFT_DEMI,
use_stocks=False,
) )
galopin.save() galopin.save()
keg.galopin = galopin keg.galopin = galopin
@ -554,13 +588,13 @@ def addKeg(request):
@permission_required('gestion.change_keg') @permission_required('gestion.change_keg')
def editKeg(request, pk): def editKeg(request, pk):
""" """
Displays a :class:`gestion.forms.KegForm` to edit a :class:`gestion.models.Keg`. Displays a :class:`gestion.forms.EditKegForm` to edit a :class:`gestion.models.Keg`.
pk pk
The primary key of the :class:`gestion.models.Keg` to edit. The primary key of the :class:`gestion.models.Keg` to edit.
""" """
keg = get_object_or_404(Keg, pk=pk) keg = get_object_or_404(Keg, pk=pk)
form = KegForm(request.POST or None, instance=keg) form = EditKegForm(request.POST or None, instance=keg)
if(form.is_valid()): if(form.is_valid()):
form.save() form.save()
messages.success(request, "Le fût a bien été modifié") messages.success(request, "Le fût a bien été modifié")

2
templates/footer.html

@ -42,6 +42,6 @@
<li><a href="https://www.facebook.com/coopesmetz/" class="icon fa-facebook alt"><span class="label">Facebook</span></a></li> <li><a href="https://www.facebook.com/coopesmetz/" class="icon fa-facebook alt"><span class="label">Facebook</span></a></li>
</ul> </ul>
</section> </section>
<p class="copyright">coope.rez v3.6.3 (release stable) &copy; 2018-2019 Yoann Pietri. <a href="{% url 'about'%}">À propos du projet</a>.</p> <p class="copyright">coope.rez v3.6.4 (release stable) &copy; 2018-2019 Yoann Pietri. <a href="{% url 'about'%}">À propos du projet</a>.</p>

Loading…
Cancel
Save