3
0
Fork 0
mirror of https://github.com/nanoy42/coope synced 2024-06-02 13:21:48 +00:00
coope/gestion/views.py

1073 lines
35 KiB
Python
Raw Normal View History

2018-11-22 21:52:15 +00:00
from django.shortcuts import render, redirect, get_object_or_404
2018-10-05 22:03:02 +00:00
from django.contrib import messages
from django.urls import reverse
2018-11-22 21:52:15 +00:00
from django.http import HttpResponse, Http404
2018-10-05 22:03:02 +00:00
from django.contrib.auth.models import User
2018-11-22 21:52:15 +00:00
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.decorators import login_required, permission_required
2018-11-25 12:52:32 +00:00
from django.utils import timezone
2018-12-24 00:30:00 +00:00
from django.http import HttpResponseRedirect
2018-10-05 22:03:02 +00:00
2019-01-05 23:01:30 +00:00
from django_tex.views import render_to_pdf
from coopeV3.acl import active_required, acl_or, admin_required
2018-11-22 21:52:15 +00:00
import simplejson as json
2018-10-05 22:03:02 +00:00
from dal import autocomplete
2018-11-22 21:52:15 +00:00
from decimal import *
2019-01-05 23:01:30 +00:00
import datetime
2018-10-05 22:03:02 +00:00
2019-01-05 23:01:30 +00:00
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
2019-01-05 23:01:30 +00:00
from users.models import CotisationHistory
2018-08-31 12:46:35 +00:00
2018-11-22 21:52:15 +00:00
@active_required
@login_required
@acl_or('gestion.add_consumptionhistory', 'gestion.add_reload', 'gestion.add_refund')
def manage(request):
2018-12-02 15:28:40 +00:00
"""
Display the manage page
**Context**
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``gestion_form``
The manage form
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``reload_form``
The :model:`gestion.Reload` form
``refund_form``
The :model:`gestion.Refund` form
``bieresPression``
A list of active :model:`gestion.Product` corresponding to draft beers
``bieresBouteille``
A list of active :model:`gestion.Product` corresponding to bottle beers
``panini``
A list of active :model:`gestion.Product` corresponding to panini items
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``food``
A list of active :model:`gestion.Product` corresponding to non-panini items
``soft``
A list of active :model:`gestion.Product` correspond to non alcoholic beverage
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``menus``
The list of active :model:`gestion.Menu`
``pay_buttons``
List of :model:`paymentMethod`
**Template**
:template:`gestion/manage.html`
"""
2018-11-22 21:52:15 +00:00
pay_buttons = PaymentMethod.objects.filter(is_active=True)
2018-10-05 22:03:02 +00:00
gestion_form = GestionForm(request.POST or None)
reload_form = ReloadForm(request.POST or None)
refund_form = RefundForm(request.POST or None)
bieresPression = []
bieresBouteille = Product.objects.filter(category=Product.BOTTLE).filter(is_active=True)
panini = Product.objects.filter(category=Product.PANINI).filter(is_active=True)
food = Product.objects.filter(category=Product.FOOD).filter(is_active=True)
soft = Product.objects.filter(category=Product.SOFT).filter(is_active=True)
menus = Menu.objects.filter(is_active=True)
kegs = Keg.objects.filter(is_active=True)
for keg in kegs:
if(keg.pinte):
bieresPression.append(keg.pinte)
if(keg.demi):
bieresPression.append(keg.demi)
if(keg.galopin):
bieresPression.append(keg.galopin)
2018-12-02 15:28:40 +00:00
return render(request, "gestion/manage.html", {
"gestion_form": gestion_form,
"reload_form": reload_form,
"refund_form": refund_form,
"bieresPression": bieresPression,
"bieresBouteille": bieresBouteille,
"panini": panini,
"food": food,
"soft": soft,
"menus": menus,
"pay_buttons": pay_buttons
})
2018-11-22 21:52:15 +00:00
2018-12-02 18:50:15 +00:00
@csrf_exempt
2018-12-02 15:28:40 +00:00
@active_required
2018-11-22 21:52:15 +00:00
@login_required
@permission_required('gestion.add_consumptionhistory')
def order(request):
2018-12-02 15:28:40 +00:00
"""
Process the given order. Called by a js/JQuery script.
"""
2018-11-22 21:52:15 +00:00
if("user" not in request.POST or "paymentMethod" not in request.POST or "amount" not in request.POST or "order" not in request.POST):
2018-11-25 12:52:32 +00:00
return HttpResponse("Erreur du POST")
2018-11-22 21:52:15 +00:00
else:
user = get_object_or_404(User, pk=request.POST['user'])
paymentMethod = get_object_or_404(PaymentMethod, pk=request.POST['paymentMethod'])
amount = Decimal(request.POST['amount'])
order = json.loads(request.POST["order"])
2018-11-27 08:07:12 +00:00
menus = json.loads(request.POST["menus"])
listPintes = json.loads(request.POST["listPintes"])
gp,_ = GeneralPreferences.objects.get_or_create(pk=1)
2018-11-27 08:07:12 +00:00
if (not order) and (not menus):
2018-11-25 12:52:32 +00:00
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
2018-11-27 08:07:12 +00:00
for m in menus:
menu = get_object_or_404(Menu, pk=m["pk"])
adherentRequired = adherentRequired or menu.adherent_required
2018-11-25 12:52:32 +00:00
if(adherentRequired and not user.profile.is_adherent):
return HttpResponse("N'est pas adhérent et devrait l'être")
# 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.")
for pinte in listPintes:
allocate(pinte, user)
2018-11-22 21:52:15 +00:00
if(paymentMethod.affect_balance):
if(user.profile.balance < amount):
2018-11-25 12:52:32 +00:00
return HttpResponse("Solde inférieur au prix de la commande")
2018-11-22 21:52:15 +00:00
else:
user.profile.debit += amount
user.save()
for o in order:
product = get_object_or_404(Product, pk=o["pk"])
2018-11-25 12:52:32 +00:00
quantity = int(o["quantity"])
if(product.category == Product.P_PRESSION):
keg = get_object_or_404(Keg, pinte=product)
if(not keg.is_active):
2018-11-27 08:07:12 +00:00
return HttpResponse("Une erreur inconnue s'est produite. Veuillez contacter le trésorier ou le président")
2018-11-25 12:52:32 +00:00
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):
2018-11-27 08:07:12 +00:00
return HttpResponse("Une erreur inconnue s'est produite. Veuillez contacter le trésorier ou le président")
2018-11-25 12:52:32 +00:00
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):
2018-11-27 08:07:12 +00:00
return HttpResponse("Une erreur inconnue s'est produite. Veuillez contacter le trésorier ou le président")
2018-11-25 12:52:32 +00:00
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=Decimal(quantity*product.amount), coopeman=request.user)
2018-11-22 21:52:15 +00:00
ch.save()
2018-11-27 08:07:12 +00:00
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()
for article in menu.articles.all():
consumption, _ = Consumption.objects.get_or_create(customer=user, product=article)
consumption.quantity += quantity
consumption.save()
2018-11-30 18:54:12 +00:00
if(article.stockHold > 0):
article.stockHold -= 1
article.save()
2018-11-22 21:52:15 +00:00
return HttpResponse("La commande a bien été effectuée")
2018-12-02 15:28:40 +00:00
@active_required
2018-11-22 21:52:15 +00:00
@login_required
@permission_required('gestion.add_reload')
2018-10-05 22:03:02 +00:00
def reload(request):
2018-12-02 15:28:40 +00:00
"""
Process a reload request
"""
2018-10-05 22:03:02 +00:00
reload_form = ReloadForm(request.POST or None)
2018-12-02 15:28:40 +00:00
if reload_form.is_valid():
reload_entry = reload_form.save(commit=False)
reload_entry.coopeman = request.user
reload_entry.save()
2018-10-05 22:03:02 +00:00
user = reload_form.cleaned_data['customer']
amount = reload_form.cleaned_data['amount']
user.profile.credit += amount
user.save()
2018-12-02 15:28:40 +00:00
messages.success(request, "Le compte de " + user.username + " a bien été crédité de " + str(amount) + "")
2018-10-05 22:03:02 +00:00
else:
messages.error(request, "Le rechargement a échoué")
return redirect(reverse('gestion:manage'))
2018-12-24 00:30:00 +00:00
@active_required
@login_required
@permission_required('gestion.delete_reload')
def cancel_reload(request, pk):
"""
Cancel a reload
"""
reload_entry = get_object_or_404(Reload, pk=pk)
if reload_entry.customer.profile.balance >= reload_entry.amount:
reload_entry.customer.profile.credit -= reload_entry.amount
reload_entry.customer.save()
reload_entry.delete()
messages.success(request, "Le rechargement a bien été annulé.")
else:
messages.error(request, "Impossible d'annuler le rechargement. Le solde deviendrait négatif.")
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
2018-12-02 15:28:40 +00:00
@active_required
2018-11-22 21:52:15 +00:00
@login_required
@permission_required('gestion.add_refund')
2018-10-05 22:03:02 +00:00
def refund(request):
2018-12-02 15:28:40 +00:00
"""
Process a refund request
"""
2018-10-05 22:03:02 +00:00
refund_form = RefundForm(request.POST or None)
2018-12-02 15:28:40 +00:00
if refund_form.is_valid():
2018-10-05 22:03:02 +00:00
user = refund_form.cleaned_data['customer']
amount = refund_form.cleaned_data['amount']
2018-12-02 15:28:40 +00:00
if amount <= user.profile.balance:
refund_entry = refund_form.save(commit = False)
refund_entry.coopeman = request.user
refund_entry.save()
2018-10-05 22:03:02 +00:00
user.profile.credit -= amount
user.save()
messages.success(request, "Le compte de " + user.username + " a bien été remboursé de " + str(amount) + "")
else:
messages.error(request, "Impossible de rembourser l'utilisateur " + user.username + " de " + str(amount) + "€ : il n'a que " + str(user.profile.balance) + "€ sur son compte.")
else:
messages.error(request, "Le remboursement a échoué")
return redirect(reverse('gestion:manage'))
2018-12-02 15:28:40 +00:00
@active_required
2018-11-30 18:54:12 +00:00
@login_required
@permission_required('gestion.delete_consumptionhistory')
def cancel_consumption(request, pk):
2018-12-02 15:28:40 +00:00
"""
Cancel a :model:`gestion.ConsumptionHistory`
``pk``
The primary key of the :model:`gestion.ConsumptionHistory` that have to be cancelled
"""
2018-11-30 18:54:12 +00:00
consumption = get_object_or_404(ConsumptionHistory, pk=pk)
user = consumption.customer
2018-12-18 10:38:20 +00:00
if consumption.paymentMethod.affect_balance:
user.profile.debit -= consumption.amount
user.save()
2018-12-13 18:26:58 +00:00
consumptionT = Consumption.objects.get(customer=user, product=consumption.product)
consumptionT.quantity -= consumption.quantity
consumptionT.save()
2018-11-30 18:54:12 +00:00
consumption.delete()
messages.success(request, "La consommation a bien été annulée")
return redirect(reverse('users:profile', kwargs={'pk': user.pk}))
2018-12-02 15:28:40 +00:00
@active_required
2018-11-30 18:54:12 +00:00
@login_required
@permission_required('gestion.delete_menuhistory')
def cancel_menu(request, pk):
2018-12-02 15:28:40 +00:00
"""
Cancel a :model:`gestion.MenuHistory`
``pk``
The primary key of the :model:`gestion.MenuHistory` that have to be cancelled
"""
2018-11-30 18:54:12 +00:00
menu_history = get_object_or_404(MenuHistory, pk=pk)
user = menu_history.customer
2018-12-18 10:38:20 +00:00
if menu_history.paymentMethod.affect_balance:
user.profile.debit -= menu_history.amount
user.save()
2018-12-13 18:26:58 +00:00
for product in manu_history.menu.articles:
consumptionT = Consumption.objects.get(customer=user, product=product)
consumptionT -= menu_history.quantity
2019-01-05 23:01:30 +00:00
consumptionT.save()
2018-11-30 18:54:12 +00:00
menu_history.delete()
messages.success(request, "La consommation du menu a bien été annulée")
return redirect(reverse('users:profile', kwargs={'pk': user.pk}))
2018-11-22 21:52:15 +00:00
########## Products ##########
2018-12-02 15:28:40 +00:00
@active_required
2018-11-22 21:52:15 +00:00
@login_required
@acl_or('gestion.add_product', 'gestion.view_product', 'gestion.add_keg', 'gestion.view_keg', 'gestion.change_keg', 'gestion.view_menu', 'gestion.add_menu')
2018-10-05 22:03:02 +00:00
def productsIndex(request):
2018-12-02 15:28:40 +00:00
"""
Display the products manage static page
**Template**
:template:`gestion/products_index.html`
"""
2018-10-05 22:03:02 +00:00
return render(request, "gestion/products_index.html")
2018-12-02 15:28:40 +00:00
@active_required
2018-11-22 21:52:15 +00:00
@login_required
@permission_required('gestion.add_product')
2018-10-05 22:03:02 +00:00
def addProduct(request):
2018-12-02 15:28:40 +00:00
"""
Form to add a :model:`gestion.Product`
**Context**
``form``
The ProductForm instance
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``form_title``
The title for the form template
``form_button``
The text of the button for the form template
**Template**
:template:`form.html`
"""
2018-10-05 22:03:02 +00:00
form = ProductForm(request.POST or None)
if(form.is_valid()):
product = form.save()
2018-10-05 22:03:02 +00:00
messages.success(request, "Le produit a bien été ajouté")
return redirect(reverse('gestion:productProfile', kwargs={'pk':product.pk}))
2018-10-05 22:03:02 +00:00
return render(request, "form.html", {"form": form, "form_title": "Ajout d'un produit", "form_button": "Ajouter"})
2018-12-02 15:28:40 +00:00
@active_required
2018-11-25 23:15:09 +00:00
@login_required
2018-12-02 15:28:40 +00:00
@permission_required('gestion.change_product')
2018-11-25 23:15:09 +00:00
def editProduct(request, pk):
2018-12-02 15:28:40 +00:00
"""
Form to edit a :model:`gestion.Product`
``pk``
The primary key of the requested :model:`gestion.Product`
**Context**
``form``
The ProductForm instance
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``form_title``
The title for the form template
``form_button``
The text of the button for the form template
**Template**
:template:`form.html`
"""
2018-11-25 23:15:09 +00:00
product = get_object_or_404(Product, pk=pk)
form = ProductForm(request.POST or None, instance=product)
if(form.is_valid()):
form.save()
messages.success(request, "Le produit a bien été modifié")
return redirect(reverse('gestion:productProfile', kwargs={'pk':product.pk}))
2018-11-25 23:15:09 +00:00
return render(request, "form.html", {"form": form, "form_title": "Modification d'un produit", "form_button": "Modifier"})
2018-12-02 15:28:40 +00:00
@active_required
2018-11-22 21:52:15 +00:00
@login_required
@permission_required('gestion.view_product')
2018-10-05 22:03:02 +00:00
def productsList(request):
2018-12-02 15:28:40 +00:00
"""
Display the list of :model:`gestion.Product`
**Context**
``products``
The list of :model:`gestion.Product`
**Template**
:template:`gestion/products_list.html`
"""
2018-10-05 22:03:02 +00:00
products = Product.objects.all()
return render(request, "gestion/products_list.html", {"products": products})
2018-12-02 15:28:40 +00:00
@active_required
2018-11-22 21:52:15 +00:00
@login_required
@permission_required('gestion.view_product')
def searchProduct(request):
2018-12-02 15:28:40 +00:00
"""
Form to search a :model:`gestion.Product`
**Context**
``form``
The SearchProductForm instance
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``form_title``
The title for the form template
``form_button``
The text of the button for the form template
**Template**
:template:`form.html`
"""
2018-11-22 21:52:15 +00:00
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"})
2018-12-02 15:28:40 +00:00
@active_required
2018-11-22 21:52:15 +00:00
@login_required
@permission_required('gestion.view_product')
def productProfile(request, pk):
2018-12-02 15:28:40 +00:00
"""
Display the profile of a :model:`gestion.Product`
``pk``
The primary key of the requested :model:`gestion.Product`
**Context**
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``product``
The :model:`gestion.Product` instance
**Template**
:model:`gestion/product_profile.html`
"""
2018-11-22 21:52:15 +00:00
product = get_object_or_404(Product, pk=pk)
return render(request, "gestion/product_profile.html", {"product": product})
2018-12-02 15:28:40 +00:00
@active_required
2018-11-22 21:52:15 +00:00
@login_required
2018-12-23 22:55:27 +00:00
def getProduct(request, pk):
2018-12-02 15:28:40 +00:00
"""
Get :model:`gestion.Product` by barcode. Called by a js/JQuery script
2018-12-23 22:55:27 +00:00
``pk``
The requested pk
2018-12-02 15:28:40 +00:00
"""
2018-12-23 22:55:27 +00:00
product = Product.objects.get(pk=pk)
if product.category == Product.P_PRESSION:
nb_pintes = 1
else:
nb_pintes = 0
data = json.dumps({"pk": product.pk, "barcode" : product.barcode, "name": product.name, "amount": product.amount, "needQuantityButton": product.needQuantityButton, "nb_pintes": nb_pintes})
2018-10-05 22:03:02 +00:00
return HttpResponse(data, content_type='application/json')
2018-12-02 15:28:40 +00:00
@active_required
2018-11-25 23:15:09 +00:00
@login_required
2018-12-02 15:28:40 +00:00
@permission_required('gestion.change_product')
2018-11-25 23:15:09 +00:00
def switch_activate(request, pk):
"""
2018-12-02 15:28:40 +00:00
Switch the active status of the requested :model:`gestion.Product`
``pk``
The primary key of the :model:`gestion.Product`
2018-11-25 23:15:09 +00:00
"""
product = get_object_or_404(Product, pk=pk)
product.is_active = 1 - product.is_active
product.save()
messages.success(request, "La disponibilité du produit a bien été changée")
return redirect(reverse('gestion:productProfile', kwargs={'pk': product.pk}))
2018-11-25 23:15:09 +00:00
2018-11-22 21:52:15 +00:00
class ProductsAutocomplete(autocomplete.Select2QuerySetView):
2018-12-02 15:28:40 +00:00
"""
Autocomplete view for all :model:`gestion.Product`
"""
2018-11-22 21:52:15 +00:00
def get_queryset(self):
qs = Product.objects.all()
if self.q:
2018-11-25 23:15:09 +00:00
qs = qs.filter(name__istartswith=self.q)
2018-11-22 21:52:15 +00:00
return qs
2018-10-05 22:03:02 +00:00
2018-12-23 22:55:27 +00:00
class ActiveProductsAutocomplete(autocomplete.Select2QuerySetView):
"""
Autocomplete view for active :model:`gestion.Product`
"""
def get_queryset(self):
qs = Product.objects.filter(is_active=True)
if self.q:
qs = qs.filter(name__istartswith=self.q)
return qs
2018-10-05 22:03:02 +00:00
########## Kegs ##########
2018-12-02 15:28:40 +00:00
@active_required
2018-11-22 21:52:15 +00:00
@login_required
@permission_required('gestion.add_keg')
2018-10-05 22:03:02 +00:00
def addKeg(request):
2018-12-02 15:28:40 +00:00
"""
Display a form to add a :model:`gestion.Keg`
**Context**
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``form``
The KegForm instance
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``form_title``
The title for the :template:`form.html` template
``form_button``
The text for the button in :template:`form.html` template
**Template**
:template:`form.html`
"""
2018-10-05 22:03:02 +00:00
form = KegForm(request.POST or None)
if(form.is_valid()):
keg = form.save()
messages.success(request, "Le fût " + keg.name + " a bien été ajouté")
2018-11-25 12:52:32 +00:00
return redirect(reverse('gestion:kegsList'))
2018-10-05 22:03:02 +00:00
return render(request, "form.html", {"form":form, "form_title": "Ajout d'un fût", "form_button": "Ajouter"})
2018-12-02 15:28:40 +00:00
@active_required
2018-11-25 12:52:32 +00:00
@login_required
2018-12-02 15:28:40 +00:00
@permission_required('gestion.change_keg')
2018-11-25 12:52:32 +00:00
def editKeg(request, pk):
2018-12-02 15:28:40 +00:00
"""
Display a form to edit a :model:`gestion.Keg`
``pk``
The primary key of the requested :model:`gestion.Keg`
**Context**
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``form``
The KegForm instance
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``form_title``
The title for the :template:`form.html` template
``form_button``
The text for the button in :template:`form.html` template
**Template**
:template:`form.html`
"""
2018-11-25 12:52:32 +00:00
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"})
2018-12-02 15:28:40 +00:00
@active_required
2018-11-25 12:52:32 +00:00
@login_required
@permission_required('gestion.open_keg')
def openKeg(request):
2018-12-02 15:28:40 +00:00
"""
Display a form to open a :model:`gestion.Keg`
**Context**
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``form``
The SelectPositiveKegForm instance
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``form_title``
The title for the :template:`form.html` template
``form_button``
The text for the button in :template:`form.html` template
**Template**
:template:`form.html`
"""
2018-11-25 12:52:32 +00:00
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"})
2018-12-02 15:28:40 +00:00
@active_required
2018-11-25 12:52:32 +00:00
@login_required
@permission_required('gestion.open_keg')
def openDirectKeg(request, pk):
2018-12-02 15:28:40 +00:00
"""
Open the requested :model:`gestion.Keg`
``pk``
The primary key of the :model:`gestion.Keg`
"""
2018-11-25 12:52:32 +00:00
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'))
2018-12-02 15:28:40 +00:00
@active_required
2018-11-25 12:52:32 +00:00
@login_required
@permission_required('gestion.close_keg')
def closeKeg(request):
2018-12-02 15:28:40 +00:00
"""
Display a form to close a :model:`gestion.Keg`
**Context**
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``form``
The SelectActiveKegForm instance
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``form_title``
The title for the :template:`form.html` template
``form_button``
The text for the button in :template:`form.html` template
**Template**
:template:`form.html`
"""
2018-11-25 12:52:32 +00:00
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"})
2018-12-02 15:28:40 +00:00
@active_required
2018-11-25 12:52:32 +00:00
@login_required
2018-12-02 15:28:40 +00:00
@permission_required('gestion.close_keg')
2018-11-25 12:52:32 +00:00
def closeDirectKeg(request, pk):
2018-12-02 15:28:40 +00:00
"""
Close the requested :model:`gestion.Keg`
``pk``
The pk of the active :model:`gestion.Keg`
"""
2018-11-25 12:52:32 +00:00
keg = get_object_or_404(Keg, pk=pk)
2018-12-02 15:28:40 +00:00
if keg.is_active:
2018-11-25 12:52:32 +00:00
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'))
2018-12-02 15:28:40 +00:00
@active_required
2018-11-25 12:52:32 +00:00
@login_required
@permission_required('gestion.view_keg')
def kegsList(request):
2018-12-02 15:28:40 +00:00
"""
Display the list of :model:`gestion.Keg`
**Context**
``kegs_active``
List of active :model:`gestion.Keg`
``kegs_inactive``
List of inactive :model:`gestion.Keg`
**Template**
:template:`gestion/kegs_list.html`
"""
2018-11-25 12:52:32 +00:00
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})
2018-12-02 15:28:40 +00:00
@active_required
2018-11-25 12:52:32 +00:00
@login_required
@permission_required('gestion.view_keghistory')
def kegH(request, pk):
2018-12-02 15:28:40 +00:00
"""
Display the history of requested :model:`gestion.Keg`
``pk``
The primary key of the requested :model:`gestion.Keg`
**Context**
``keg``
The :model:`gestion.Keg` instance
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``kegHistory``
List of :model:`gestion.KegHistory` attached to keg
**Template**
:template:`gestion/kegh.html`
"""
2018-11-25 12:52:32 +00:00
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):
2018-12-02 15:28:40 +00:00
"""
Autocomplete view for active :model:`gestion.Keg`
"""
2018-11-25 12:52:32 +00:00
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):
2018-12-02 15:28:40 +00:00
"""
Autocomplete view for :model:`gestion.Keg` with positive stockHold
"""
2018-11-25 12:52:32 +00:00
def get_queryset(self):
qs = Keg.objects.filter(stockHold__gt = 0)
if self.q:
qs = qs.filter(name__istartswith=self.q)
return qs
2018-10-05 22:03:02 +00:00
########## Menus ##########
2018-12-02 15:28:40 +00:00
@active_required
2018-11-22 21:52:15 +00:00
@login_required
@permission_required('gestion.add_menu')
2018-10-05 22:03:02 +00:00
def addMenu(request):
2018-12-02 15:28:40 +00:00
"""
Display a form to add a :model:`gestion.Menu`
**Context**
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``form``
The MenuForm instance
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``form_title``
The title for the :template:`form.html` template
``form_button``
The text for the button in :template:`form.html` template
**Template**
:template:`form.html`
"""
2018-10-05 22:03:02 +00:00
form = MenuForm(request.POST or None)
extra_css = "#id_articles{height:200px;}"
if(form.is_valid()):
menu = form.save()
messages.success(request, "Le menu " + menu.name + " a bien été ajouté")
2018-11-25 23:15:09 +00:00
return redirect(reverse('gestion:menusList'))
2018-10-05 22:03:02 +00:00
return render(request, "form.html", {"form":form, "form_title": "Ajout d'un menu", "form_button": "Ajouter", "extra_css": extra_css})
2018-12-02 15:28:40 +00:00
@active_required
2018-11-25 23:15:09 +00:00
@login_required
2018-12-02 15:28:40 +00:00
@permission_required('gestion.change_menu')
2018-11-25 23:15:09 +00:00
def edit_menu(request, pk):
2018-12-02 15:28:40 +00:00
"""
Display a form to edit a :model:`gestion.Menu`
``pk``
The primary key of requested :model:`gestion.Menu`
**Context**
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``form``
The MenuForm instance
2019-01-05 23:01:30 +00:00
2018-12-02 15:28:40 +00:00
``form_title``
The title for the :template:`form.html` template
``form_button``
The text for the button in :template:`form.html` template
**Template**
:template:`form.html`
"""
2018-11-25 23:15:09 +00:00
menu = get_object_or_404(Menu, pk=pk)
form = MenuForm(request.POST or None, instance=menu)
extra_css = "#id_articles{height:200px;}"
if form.is_valid():
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})
2018-11-22 21:52:15 +00:00
2018-12-02 15:28:40 +00:00
@active_required
2018-11-22 21:52:15 +00:00
@login_required
@permission_required('gestion.view_menu')
def searchMenu(request):
"""
2018-12-02 15:28:40 +00:00
Search a :model:`gestion.Menu` via SearchMenuForm instance
2018-11-22 21:52:15 +00:00
**Context**
``form_entete``
The form title.
``form``
The SearchMenuForm instance.
``form_button``
The content of the form button.
**Template**
:template:`form.html`
"""
form = SearchMenuForm(request.POST or None)
if(form.is_valid()):
2018-11-25 23:15:09 +00:00
menu = form.cleaned_data['menu']
return redirect(reverse('gestion:editMenu', kwargs={'pk':menu.pk}))
2018-11-22 21:52:15 +00:00
return render(request, "form.html", {"form": form, "form_title": "Recherche d'un menu", "form_button": "Modifier"})
2018-12-02 15:28:40 +00:00
@active_required
2018-11-25 23:15:09 +00:00
@login_required
@permission_required('gestion.view_menu')
def menus_list(request):
2018-12-02 15:28:40 +00:00
"""
Display the :model:`gestion.Menu` list
**Context**
``menus``
The list of :model:`gestion.Menu` instances
**Template**
:template:`gestion/menus_list.html`
"""
2018-11-25 23:15:09 +00:00
menus = Menu.objects.all()
return render(request, "gestion/menus_list.html", {"menus": menus})
2018-12-02 15:28:40 +00:00
@active_required
2018-11-25 23:15:09 +00:00
@login_required
2018-12-02 15:28:40 +00:00
@permission_required('gestion.change_menu')
2018-11-25 23:15:09 +00:00
def switch_activate_menu(request, pk):
"""
2018-12-02 15:28:40 +00:00
Switch active status of a :model:`gestion.Menu`
``pk``
The pk of the :model:`gestion.Menu`
2018-11-25 23:15:09 +00:00
"""
menu = get_object_or_404(Menu, pk=pk)
menu.is_active = 1 - menu.is_active
menu.save()
messages.success(request, "La disponibilité du menu a bien été changée")
return redirect(reverse('gestion:menusList'))
2018-12-02 15:28:40 +00:00
@active_required
2018-11-27 08:07:12 +00:00
@login_required
2018-12-02 15:28:40 +00:00
@permission_required('gestion.view_menu')
2018-12-23 22:55:27 +00:00
def get_menu(request, pk):
2018-12-02 15:28:40 +00:00
"""
Search :model:`gestion.Menu` by barcode
2018-12-23 22:55:27 +00:00
``pk``
The requested pk
2018-12-02 15:28:40 +00:00
"""
2018-12-23 22:55:27 +00:00
menu = get_object_or_404(Menu, pk=pk)
nb_pintes = 0
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})
2018-11-27 08:07:12 +00:00
return HttpResponse(data, content_type='application/json')
2018-11-22 21:52:15 +00:00
class MenusAutocomplete(autocomplete.Select2QuerySetView):
2018-12-02 15:28:40 +00:00
"""
Used as autcomplete for all :model:`gestion.Menu`
"""
2018-11-22 21:52:15 +00:00
def get_queryset(self):
qs = Menu.objects.all()
if self.q:
qs = qs.filter(name__istartswith=self.q)
return qs
2018-12-02 15:28:40 +00:00
2018-11-22 21:52:15 +00:00
########## Ranking ##########
2018-12-02 15:28:40 +00:00
@active_required
2018-11-22 21:52:15 +00:00
@login_required
def ranking(request):
2018-12-02 15:28:40 +00:00
"""
Display the ranking page
**Context**
``bestBuyers``
List of the 25 best buyers
``bestDrinkers``
List of the 25 best drinkers
**Template**
:template: `gestion/ranking.html`
"""
2018-11-22 21:52:15 +00:00
bestBuyers = User.objects.order_by('-profile__debit')[:25]
customers = User.objects.all()
list = []
for customer in customers:
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})
########## Pinte monitoring ##########
def allocate(pinte_pk, user):
"""
Allocate a pinte to a user or release the pinte if user is None
"""
try:
pinte = Pinte.objects.get(pk=pinte_pk)
if pinte.current_owner is not None:
pinte.previous_owner = pinte.current_owner
pinte.current_owner = user
pinte.save()
return True
except Pinte.DoesNotExist:
2018-12-23 11:54:37 +00:00
return False
2018-12-23 13:36:29 +00:00
@active_required
@login_required
@permission_required('gestion.change_pinte')
def release(request, pinte_pk):
"""
View to release a pinte
"""
if allocate(pinte_pk, None):
messages.success(request, "La pinte a bien été libérée")
else:
messages.error(request, "Impossible de libérer la pinte")
return redirect(reverse('gestion:pintesList'))
2019-01-05 23:01:30 +00:00
2018-12-23 11:54:37 +00:00
@active_required
@login_required
@permission_required('gestion.add_pinte')
2018-12-23 13:36:29 +00:00
def add_pintes(request):
2018-12-23 12:05:41 +00:00
form = PinteForm(request.POST or None)
2018-12-23 11:54:37 +00:00
if form.is_valid():
ids = form.cleaned_data['ids']
if ids != "":
ids = ids.split(" ")
else:
ids = range(form.cleaned_data['begin'], form.cleaned_data['end'] + 1)
i = 0
for id in ids:
if not Pinte.objects.filter(pk=id).exists():
new_pinte = Pinte(pk=int(id))
new_pinte.save()
i += 1
messages.success(request, str(i) + " pinte(s) a(ont) été ajoutée(s)")
return redirect(reverse('gestion:productsIndex'))
2018-12-23 12:05:41 +00:00
return render(request, "form.html", {"form": form, "form_title": "Ajouter des pintes", "form_button": "Ajouter"})
@active_required
@login_required
@permission_required('gestion.change_pinte')
def release_pintes(request):
form = PinteForm(request.POST or None)
if form.is_valid():
ids = form.cleaned_data['ids']
if ids != "":
ids = ids.split(" ")
else:
ids = range(form.cleaned_data['begin'], form.cleaned_data['end'] + 1)
i = 0
for id in ids:
if allocate(id, None):
i += 1
messages.success(request, str(i) + " pinte(s) a(ont) été libérée(s)")
return redirect(reverse('gestion:productsIndex'))
2018-12-23 13:36:29 +00:00
return render(request, "form.html", {"form": form, "form_title": "Libérer des pintes", "form_button": "Libérer"})
@active_required
@login_required
@permission_required('gestion.view_pinte')
def pintes_list(request):
free_pintes = Pinte.objects.filter(current_owner=None)
taken_pintes = Pinte.objects.exclude(current_owner=None)
2018-12-23 20:21:30 +00:00
return render(request, "gestion/pintes_list.html", {"free_pintes": free_pintes, "taken_pintes": taken_pintes})
@active_required
@login_required
@permission_required('auth.view_user')
def pintes_user_list(request):
pks = [x.pk for x in User.objects.all() if x.profile.nb_pintes > 0]
users = User.objects.filter(pk__in=pks)
2019-01-05 23:01:30 +00:00
return render(request, "gestion/pintes_user_list.html", {"users": users})
@active_required
@login_required
@admin_required
def gen_releve(request):
form = GenerateReleveForm(request.POST or None)
if form.is_valid():
begin, end = form.cleaned_data['begin'], form.cleaned_data['end']
consumptions = ConsumptionHistory.objects.filter(date__gte=begin).filter(date__lte=end).order_by('-date')
reloads = Reload.objects.filter(date__gt=begin).filter(date__lt=end).order_by('-date')
refunds = Refund.objects.filter(date__gt=begin).filter(date__lt=end).order_by('-date')
cotisations = CotisationHistory.objects.filter(paymentDate__gt=begin).filter(paymentDate__lt=end).order_by('-paymentDate')
especes = PaymentMethod.objects.get(name="Espèces")
lydia = PaymentMethod.objects.get(name="Lydia")
cheque = PaymentMethod.objects.get(name="Chèque")
value_especes = 0
value_lydia = 0
value_cheque = 0
for consumption in consumptions:
pm = consumption.paymentMethod
if pm == especes:
value_especes += consumption.amount
elif pm == lydia:
value_lydia += consumption.amount
elif pm == cheque:
value_cheque += consumption.amount
for reload in reloads:
pm = reload.PaymentMethod
if pm == especes:
value_especes += reload.amount
elif pm == lydia:
value_lydia += reload.amount
elif pm == cheque:
value_cheque += reload.amount
for refund in refunds:
value_especes -= refund.amount
for cot in cotisations:
pm = cot.paymentMethod
if pm == especes:
value_especes += cot.amount
elif pm == lydia:
value_lydia += cot.amount
elif pm == cheque:
value_cheque += cot.amount
now = datetime.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"})