3
0
Fork 0
mirror of https://github.com/nanoy42/coope synced 2024-11-22 03:13:12 +00:00

Merge pull request #18 from nanoy42/dev

Dev
This commit is contained in:
Yoann Pietri 2019-08-29 12:47:48 +02:00 committed by GitHub
commit d7e21b6600
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 111 additions and 27 deletions

View file

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

View file

@ -59,10 +59,10 @@ class ProductAdmin(SimpleHistoryAdmin):
"""
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')
search_fields = ('name',)
list_filter = ('is_active', 'adherentRequired', 'category')
list_filter = ('is_active', 'adherentRequired', 'category', 'use_stocks')
class ReloadAdmin(SimpleHistoryAdmin):
"""

View file

@ -42,9 +42,9 @@ class ProductForm(forms.ModelForm):
fields = "__all__"
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:
@ -52,9 +52,24 @@ class KegForm(forms.ModelForm):
fields = ["name", "stockHold", "amount", "capacity"]
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)])
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):
cleaned_data = super().clean()

View file

@ -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 ?'),
),
]

View file

@ -27,6 +27,13 @@ class Category(models.Model):
"""
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):
"""
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
"""
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()
def __str__(self):

View file

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

View file

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

View file

@ -22,7 +22,7 @@ from decimal import *
import os
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 users.models import School
from preferences.models import PaymentMethod, GeneralPreferences, Cotisation, DivideHistory, PriceProfile
@ -160,7 +160,7 @@ def order(request):
kegHistory.quantitySold += Decimal(quantity * 0.125)
kegHistory.amountSold += Decimal(quantity * product.amount)
kegHistory.save()
else:
if product.use_stocks:
if(product.stock > quantity):
product.stock -= quantity
product.save()
@ -197,6 +197,31 @@ def order(request):
consumption, _ = Consumption.objects.get_or_create(customer=user, product=article)
consumption.quantity += quantity
consumption.save()
if(article.draft_category == Product.DRAFT_PINTE):
keg = get_object_or_404(Keg, pinte=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.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()
@ -296,6 +321,7 @@ def cancel_consumption(request, pk):
consumptionT = Consumption.objects.get(customer=user, product=consumption.product)
consumptionT.quantity -= consumption.quantity
consumptionT.save()
if product.use_stocks:
product.stock += consumption.quantity
product.save()
consumption.delete()
@ -467,6 +493,7 @@ class ActiveProductsAutocomplete(autocomplete.Select2QuerySetView):
def update_stock(request, pk):
product = get_object_or_404(Product, pk=pk)
if("stock" in request.GET):
if product.use_stocks:
product.stock = request.GET.get("stock")
product.save()
return HttpResponse("Le stock a bien été mis à jour")
@ -488,12 +515,16 @@ def stocks(request):
@permission_required('gestion.add_keg')
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():
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)
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 = ceil(10*pinte_price)/10
name = form.cleaned_data["name"][4:]
@ -509,7 +540,8 @@ def addKeg(request):
deg = form.cleaned_data["deg"],
adherentRequired = True,
showingMultiplier = 1,
draft_category = Product.DRAFT_PINTE
draft_category = Product.DRAFT_PINTE,
use_stocks=False,
)
pinte.save()
keg.pinte = pinte
@ -524,7 +556,8 @@ def addKeg(request):
deg = form.cleaned_data["deg"],
adherentRequired = True,
showingMultiplier = 1,
draft_category = Product.DRAFT_DEMI
draft_category = Product.DRAFT_DEMI,
use_stocks=False,
)
demi.save()
keg.demi = demi
@ -540,7 +573,8 @@ def addKeg(request):
deg = form.cleaned_data["deg"],
adherentRequired = True,
showingMultiplier = 1,
draft_category = Product.DRAFT_DEMI
draft_category = Product.DRAFT_DEMI,
use_stocks=False,
)
galopin.save()
keg.galopin = galopin
@ -554,13 +588,13 @@ def addKeg(request):
@permission_required('gestion.change_keg')
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
The primary key of the :class:`gestion.models.Keg` to edit.
"""
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()):
form.save()
messages.success(request, "Le fût a bien été modifié")

View file

@ -42,6 +42,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.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>