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

1030 lines
42 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
2019-05-03 21:27:11 +00:00
from django.contrib.auth.models import User, Group
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
2019-01-22 19:27:18 +00:00
from django.db import transaction
2018-10-05 22:03:02 +00:00
2019-01-22 19:27:18 +00:00
from datetime import datetime, timedelta
2019-01-05 23:01:30 +00:00
2019-01-22 19:27:18 +00:00
from django_tex.views import render_to_pdf
2019-01-05 23:01:30 +00:00
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 *
2018-10-05 22:03:02 +00:00
2019-05-03 19:09:32 +00:00
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
2019-05-03 21:27:11 +00:00
from users.models import School
2019-06-23 08:54:21 +00:00
from preferences.models import PaymentMethod, GeneralPreferences, Cotisation, DivideHistory
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
"""
2019-02-28 12:18:41 +00:00
Displays the manage view.
2018-12-02 15:28:40 +00:00
"""
2019-05-03 19:09:32 +00:00
categories = Category.objects.exclude(order=0).order_by('order')
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 = []
menus = Menu.objects.filter(is_active=True)
kegs = Keg.objects.filter(is_active=True)
2019-01-06 04:18:31 +00:00
gp, _ = GeneralPreferences.objects.get_or_create(pk=1)
2019-01-22 19:27:18 +00:00
cotisations = Cotisation.objects.all()
2019-01-06 04:18:31 +00:00
floating_buttons = gp.floating_buttons
2018-10-05 22:03:02 +00:00
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,
2019-05-03 19:09:32 +00:00
"categories": categories,
2019-01-06 04:18:31 +00:00
"pay_buttons": pay_buttons,
"floating_buttons": floating_buttons,
2019-01-22 19:27:18 +00:00
"cotisations": cotisations
2018-12-02 15:28:40 +00:00
})
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
"""
2019-02-28 12:18:41 +00:00
Processes the given order. The order is passed through POST.
2018-12-02 15:28:40 +00:00
"""
2019-01-22 19:27:18 +00:00
error_message = "Impossible d'effectuer la transaction. Toute opération abandonnée. Veuillez contacter le président ou le trésorier"
try:
with transaction.atomic():
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 Exception("Erreur du post")
2018-11-25 12:52:32 +00:00
else:
2019-01-22 19:27:18 +00:00
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"])
menus = json.loads(request.POST["menus"])
listPintes = json.loads(request.POST["listPintes"])
cotisations = json.loads(request.POST['cotisations'])
gp,_ = GeneralPreferences.objects.get_or_create(pk=1)
if (not order) and (not menus) and (not cotisations):
error_message = "Pas de commande"
raise Exception(error_message)
if(cotisations):
for co in cotisations:
cotisation = Cotisation.objects.get(pk=co['pk'])
for i in range(co['quantity']):
cotisation_history = CotisationHistory(cotisation=cotisation)
if(paymentMethod.affect_balance):
if(user.profile.balance >= cotisation_history.cotisation.amount):
user.profile.debit += cotisation_history.cotisation.amount
else:
error_message = "Solde insuffisant"
raise Exception(error_message)
cotisation_history.user = user
cotisation_history.coopeman = request.user
cotisation_history.amount = cotisation.amount
cotisation_history.duration = cotisation.duration
cotisation_history.paymentMethod = paymentMethod
if(user.profile.cotisationEnd and user.profile.cotisationEnd > timezone.now()):
cotisation_history.endDate = user.profile.cotisationEnd + timedelta(days=cotisation.duration)
else:
cotisation_history.endDate = timezone.now() + timedelta(days=cotisation.duration)
user.profile.cotisationEnd = cotisation_history.endDate
user.save()
cotisation_history.save()
adherentRequired = False
for o in order:
product = get_object_or_404(Product, pk=o["pk"])
adherentRequired = adherentRequired or product.adherentRequired
for m in menus:
menu = get_object_or_404(Menu, pk=m["pk"])
adherentRequired = adherentRequired or menu.adherent_required
if(adherentRequired and not user.profile.is_adherent):
error_message = "N'est pas adhérent et devrait l'être."
raise Exception(error_message)
# 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.use_pinte_monitoring and gp.lost_pintes_allowed and user.profile.nb_pintes >= gp.lost_pintes_allowed):
error_message = "Impossible de réaliser la commande : l'utilisateur a perdu trop de pintes."
raise Exception(error_message)
for pinte in listPintes:
allocate(pinte, user)
for o in order:
product = get_object_or_404(Product, pk=o["pk"])
quantity = int(o["quantity"])
2019-05-06 07:40:40 +00:00
if(product.draft_category == Product.DRAFT_PINTE):
2019-01-22 19:27:18 +00:00
keg = get_object_or_404(Keg, pinte=product)
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()
2019-05-06 07:40:40 +00:00
elif(product.draft_category == Product.DRAFT_DEMI):
2019-01-22 19:27:18 +00:00
keg = get_object_or_404(Keg, demi=product)
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()
2019-05-06 07:40:40 +00:00
elif(product.draft_category == Product.DRAFT_GALOPIN):
2019-01-22 19:27:18 +00:00
keg = get_object_or_404(Keg, galopin=product)
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()
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)
ch.save()
2019-06-12 21:53:01 +00:00
user.profile.alcohol += Decimal(quantity * float(product.deg) * product.volume * 0.79 /10 /1000)
2019-01-26 16:02:23 +00:00
if(paymentMethod.affect_balance):
if(user.profile.balance >= Decimal(product.amount*quantity)):
user.profile.debit += Decimal(product.amount*quantity)
else:
error_message = "Solde insuffisant"
raise Exception(error_message)
2019-01-22 19:27:18 +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()
2019-01-26 16:02:23 +00:00
if(paymentMethod.affect_balance):
if(user.profile.balance >= Decimal(product.amount*quantity)):
user.profile.debit += Decimal(product.amount*quantity)
else:
error_message = "Solde insuffisant"
raise Exception(error_message)
2019-01-22 19:27:18 +00:00
for article in menu.articles.all():
consumption, _ = Consumption.objects.get_or_create(customer=user, product=article)
consumption.quantity += quantity
consumption.save()
if(article.stockHold > 0):
article.stockHold -= 1
article.save()
2019-06-12 21:53:01 +00:00
user.profile.alcohol += Decimal(quantity * float(product.deg) * product.volume * 0.79 /10 /1000)
2019-01-24 21:33:48 +00:00
user.save()
2019-01-22 19:27:18 +00:00
return HttpResponse("La commande a bien été effectuée")
except Exception as e:
return HttpResponse(error_message)
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.add_reload')
2018-10-05 22:03:02 +00:00
def reload(request):
2018-12-02 15:28:40 +00:00
"""
2019-02-28 12:18:41 +00:00
Displays a :class:`Reload form <gestion.forms.reloadForm>`.
2018-12-02 15:28:40 +00:00
"""
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):
"""
2019-02-28 12:18:41 +00:00
Delete a :class:`gestion.models.Reload`.
pk
The primary key of the reload to delete.
2018-12-24 00:30:00 +00:00
"""
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
"""
2019-02-28 12:18:41 +00:00
Displays a :class:`Refund form <gestion.forms.RefundForm>`.
2018-12-02 15:28:40 +00:00
"""
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
"""
2019-02-28 12:18:41 +00:00
Delete a :class:`consumption history <gestion.models.ConsumptionHistory>`.
2018-12-02 15:28:40 +00:00
2019-02-28 12:18:41 +00:00
pk
The primary key of the consumption history to delete.
2018-12-02 15:28:40 +00:00
"""
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
2019-06-12 21:53:01 +00:00
user.profile.alcohol -= Decimal(consumption.quantity * float(consumption.product.deg) * consumption.product.volume * 0.79 /10 /1000)
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
"""
2019-02-28 12:18:41 +00:00
Delete a :class:`menu history <gestion.models.MenuHistory>`.
2018-12-02 15:28:40 +00:00
2019-02-28 12:18:41 +00:00
pk
The primary key of the menu history to delete.
2018-12-02 15:28:40 +00:00
"""
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()
2019-06-12 21:53:01 +00:00
user.profile.alcohol -= Decimal(menu_history.quantity * float(menu_history.product.deg) * menu_history.product.volume * 0.79 /10 /1000)
user.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
"""
2019-02-28 12:18:41 +00:00
Displays the products manage static page.
2018-12-02 15:28:40 +00:00
"""
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
"""
2019-02-28 12:18:41 +00:00
Displays a :class:`gestion.forms.ProductForm` to add a product.
2018-12-02 15:28:40 +00:00
"""
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}))
2019-01-17 22:16:43 +00:00
return render(request, "form.html", {"form": form, "form_title": "Ajout d'un produit", "form_button": "Ajouter", "form_button_icon": "plus-square"})
2018-10-05 22:03:02 +00:00
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
"""
2019-02-28 12:18:41 +00:00
Displays a :class:`gestion.forms.ProductForm` to edit a product.
2018-12-02 15:28:40 +00:00
2019-02-28 12:18:41 +00:00
pk
The primary key of the the :class:`gestion.models.Product` to edit.
2018-12-02 15:28:40 +00:00
"""
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}))
2019-01-17 22:16:43 +00:00
return render(request, "form.html", {"form": form, "form_title": "Modification d'un produit", "form_button": "Modifier", "form_button_icon": "pencil-alt"})
2018-11-25 23:15:09 +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_product')
2018-10-05 22:03:02 +00:00
def productsList(request):
2018-12-02 15:28:40 +00:00
"""
2019-02-28 12:18:41 +00:00
Display the list of :class:`products <gestion.models.Product>`.
2018-12-02 15:28:40 +00:00
"""
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
"""
2019-02-28 12:18:41 +00:00
Displays a :class:`gestion.forms.SearchProduct` to search a :class:`gestion.models.Product`.
2018-12-02 15:28:40 +00:00
"""
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 }))
2019-01-17 22:16:43 +00:00
return render(request, "form.html", {"form": form, "form_title":"Rechercher un produit", "form_button": "Rechercher", "form_button_icon": "search"})
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_product')
def productProfile(request, pk):
2018-12-02 15:28:40 +00:00
"""
2019-02-28 12:18:41 +00:00
Displays the profile of a :class:`gestion.models.Product`.
2018-12-02 15:28:40 +00:00
2019-02-28 12:18:41 +00:00
pk
The primary key of the :class:`gestion.models.Product` to display profile.
2018-12-02 15:28:40 +00:00
"""
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
"""
2019-02-28 12:18:41 +00:00
Get a :class:`gestion.models.Product` by barcode and return it in JSON format.
2018-12-02 15:28:40 +00:00
2019-02-28 12:18:41 +00:00
pk
The primary key of the :class:`gestion.models.Product` to get infos.
2018-12-02 15:28:40 +00:00
"""
2018-12-23 22:55:27 +00:00
product = Product.objects.get(pk=pk)
2019-05-06 07:40:40 +00:00
if product.category == Product.DRAFT_PINTE:
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):
"""
2019-02-28 12:18:41 +00:00
Switch the active status of the requested :class:`gestion.models.Product`.
2018-12-02 15:28:40 +00:00
2019-02-28 12:18:41 +00:00
pk
The primary key of the :class:`gestion.models.Product` to display profile.
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
"""
2019-02-28 12:18:41 +00:00
Autocomplete view for all :class:`products <gestion.models.Product>`.
2018-12-02 15:28:40 +00:00
"""
2018-11-22 21:52:15 +00:00
def get_queryset(self):
qs = Product.objects.all()
if self.q:
2019-01-23 11:31:33 +00:00
qs = qs.filter(name__icontains=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):
"""
2019-02-28 12:18:41 +00:00
Autocomplete view for active :class:`products <gestion.models.Product>`.
2018-12-23 22:55:27 +00:00
"""
def get_queryset(self):
qs = Product.objects.filter(is_active=True)
if self.q:
2019-01-23 11:31:33 +00:00
qs = qs.filter(name__icontains=self.q)
2018-12-23 22:55:27 +00:00
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
"""
2019-02-28 12:18:41 +00:00
Displays a :class:`gestion.forms.KegForm` to add a :class:`gestion.models.Keg`.
2018-12-02 15:28:40 +00:00
"""
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'))
2019-01-17 22:16:43 +00:00
return render(request, "form.html", {"form":form, "form_title": "Ajout d'un fût", "form_button": "Ajouter", "form_button_icon": "plus-square"})
2018-10-05 22:03:02 +00:00
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
"""
2019-02-28 12:18:41 +00:00
Displays a :class:`gestion.forms.KegForm` to edit a :class:`gestion.models.Keg`.
2019-01-05 23:01:30 +00:00
2019-02-28 12:18:41 +00:00
pk
The primary key of the :class:`gestion.models.Keg` to edit.
2018-12-02 15:28:40 +00:00
"""
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'))
2019-01-17 22:16:43 +00:00
return render(request, "form.html", {"form": form, "form_title": "Modification d'un fût", "form_button": "Modifier", "form_button_icon": "pencil-alt"})
2018-11-25 12:52:32 +00:00
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
"""
2019-02-28 12:18:41 +00:00
Displays a :class:`gestion.forms.SelectPositiveKegForm` to open a :class:`gestion.models.Keg`.
2018-12-02 15:28:40 +00:00
"""
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'))
2019-01-17 22:16:43 +00:00
return render(request, "form.html", {"form": form, "form_title":"Percutage d'un fût", "form_button":"Percuter", "form_button_icon": "fill-drip"})
2018-11-25 12:52:32 +00:00
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
"""
2019-02-28 12:18:41 +00:00
Opens a class:`gestion.models.Keg`.
2018-12-02 15:28:40 +00:00
2019-02-28 12:18:41 +00:00
pk
The primary key of the class:`gestion.models.Keg` to open.
2018-12-02 15:28:40 +00:00
"""
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
"""
2019-02-28 12:18:41 +00:00
Displays a :class:`gestion.forms.SelectPositiveKegForm` to open a :class:`gestion.models.Keg`.
2018-12-02 15:28:40 +00:00
"""
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'))
2019-01-17 22:16:43 +00:00
return render(request, "form.html", {"form": form, "form_title":"Fermeture d'un fût", "form_button":"Fermer le fût", "form_button_icon": "fill"})
2018-11-25 12:52:32 +00:00
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
"""
2019-02-28 12:18:41 +00:00
Closes a class:`gestion.models.Keg`.
2018-12-02 15:28:40 +00:00
2019-02-28 12:18:41 +00:00
pk
The primary key of the class:`gestion.models.Keg` to open.
2018-12-02 15:28:40 +00:00
"""
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
"""
2019-02-28 12:18:41 +00:00
Display the list of :class:`kegs <gestion.models.Keg>`.
2018-12-02 15:28:40 +00:00
"""
2018-11-25 12:52:32 +00:00
kegs_active = KegHistory.objects.filter(isCurrentKegHistory=True)
2019-01-24 21:26:38 +00:00
ids_actives = kegs_active.values('keg__id')
2018-11-25 12:52:32 +00:00
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
"""
2019-02-28 12:18:41 +00:00
Display the :class:`history <gestion.models.KegHistory>` of requested :class:`gestion.models.Keg`.
2018-12-02 15:28:40 +00:00
"""
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
"""
2019-02-28 12:18:41 +00:00
Autocomplete view for active :class:`kegs <gestion.models.Keg>`.
2018-12-02 15:28:40 +00:00
"""
2018-11-25 12:52:32 +00:00
def get_queryset(self):
qs = Keg.objects.filter(is_active = True)
if self.q:
2019-01-23 11:31:33 +00:00
qs = qs.filter(name__icontains=self.q)
2018-11-25 12:52:32 +00:00
return qs
class KegPositiveAutocomplete(autocomplete.Select2QuerySetView):
2018-12-02 15:28:40 +00:00
"""
2019-02-28 12:18:41 +00:00
Autocomplete view for :class:`kegs <gestion.models.Keg>` with positive stockHold.
2018-12-02 15:28:40 +00:00
"""
2018-11-25 12:52:32 +00:00
def get_queryset(self):
qs = Keg.objects.filter(stockHold__gt = 0)
if self.q:
2019-01-23 11:31:33 +00:00
qs = qs.filter(name__icontains=self.q)
2018-11-25 12:52:32 +00:00
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
"""
2019-02-28 12:18:41 +00:00
Display a :class:`gestion.forms.MenuForm` to add a :class:`gestion.models.Menu`.
2018-12-02 15:28:40 +00:00
"""
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'))
2019-01-17 22:16:43 +00:00
return render(request, "form.html", {"form":form, "form_title": "Ajout d'un menu", "form_button": "Ajouter", "form_button_icon": "plus-square", "extra_css": extra_css})
2018-10-05 22:03:02 +00:00
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
"""
2019-02-28 12:18:41 +00:00
Displays a :class:`gestion.forms.MenuForm` to edit a :class:`gestion.models.Menu`.
2018-12-02 15:28:40 +00:00
2019-02-28 12:18:41 +00:00
pk
The primary key of the :class:`gestion.models.Menu` to edit.
2018-12-02 15:28:40 +00:00
"""
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'))
2019-01-17 22:16:43 +00:00
return render(request, "form.html", {"form": form, "form_title": "Modification d'un menu", "form_button": "Modifier", "form_button_icon": "pencil-alt", "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):
"""
2019-02-28 12:18:41 +00:00
Displays a :class:`gestion.forms.SearchMenuForm` to search a :class:`gestion.models.Menu`.
2018-11-22 21:52:15 +00:00
"""
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}))
2019-01-17 22:16:43 +00:00
return render(request, "form.html", {"form": form, "form_title": "Recherche d'un menu", "form_button": "Modifier", "form_button_icon": "search"})
2018-11-22 21:52:15 +00:00
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
"""
2019-02-28 12:18:41 +00:00
Display the list of :class:`menus <gestion.models.Menu>`.
2018-12-02 15:28:40 +00:00
"""
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):
"""
2019-02-28 12:18:41 +00:00
Switch active status of a :class:`gestion.models.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
"""
2019-02-28 12:18:41 +00:00
Get a :class:`gestion.models.Menu` by pk and return it in JSON format.
2018-12-02 15:28:40 +00:00
2019-02-28 12:18:41 +00:00
pk
The primary key of the :class:`gestion.models.Menu`.
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:
2019-05-06 07:40:40 +00:00
if article.category == Product.DRAFT_PINTE:
nb_pintes +=1
2019-01-22 19:27:18 +00:00
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
"""
2019-02-28 12:18:41 +00:00
Autocomplete view for active :class:`menus <gestion.models.Menu>`.
2018-12-02 15:28:40 +00:00
"""
2018-11-22 21:52:15 +00:00
def get_queryset(self):
qs = Menu.objects.all()
if self.q:
2019-01-23 11:31:33 +00:00
qs = qs.filter(name__icontains=self.q)
2018-11-22 21:52:15 +00:00
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
"""
2019-02-28 12:18:41 +00:00
Displays the ranking page.
2018-12-02 15:28:40 +00:00
"""
2018-11-22 21:52:15 +00:00
bestBuyers = User.objects.order_by('-profile__debit')[:25]
2019-06-10 23:28:22 +00:00
bestDrinkers = User.objects.order_by('-profile__alcohol')[:25]
2019-01-18 14:38:48 +00:00
form = SearchProductForm(request.POST or None)
if(form.is_valid()):
product_ranking = form.cleaned_data['product'].ranking
else:
product_ranking = None
return render(request, "gestion/ranking.html", {"bestBuyers": bestBuyers, "bestDrinkers": bestDrinkers, "product_ranking": product_ranking, "form": form})
########## Pinte monitoring ##########
def allocate(pinte_pk, user):
"""
2019-02-28 12:18:41 +00:00
Allocate a :class:`gestion.models.Pinte` to a user (:class:`django.contrib.auth.models.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):
"""
2019-02-28 12:18:41 +00:00
View to release a :class:`gestion.models.Pinte`.
pinte_pk
The primary key of the :class:`gestion.models.Pinte` to release.
2018-12-23 13:36:29 +00:00
"""
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):
2019-02-28 12:18:41 +00:00
"""
Displays a :class:`gestion.forms.PinteForm` to add one or more :class:`gestion.models.Pinte`.
"""
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'))
2019-01-17 22:16:43 +00:00
return render(request, "form.html", {"form": form, "form_title": "Ajouter des pintes", "form_button": "Ajouter", "form_button_icon": "plus-square"})
2018-12-23 12:05:41 +00:00
@active_required
@login_required
@permission_required('gestion.change_pinte')
def release_pintes(request):
2019-02-28 12:18:41 +00:00
"""
Displays a :class:`gestion.forms.PinteForm` to release one or more :class:`gestion.models.Pinte`.
"""
2018-12-23 12:05:41 +00:00
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'))
2019-01-17 22:16:43 +00:00
return render(request, "form.html", {"form": form, "form_title": "Libérer des pintes", "form_button": "Libérer", "form_button_icon": "glass-whiskey"})
2018-12-23 13:36:29 +00:00
@active_required
@login_required
@permission_required('gestion.view_pinte')
def pintes_list(request):
2019-02-28 12:18:41 +00:00
"""
Displays the list of :class:`gestion.models.Pinte`
"""
2018-12-23 13:36:29 +00:00
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):
2019-02-28 12:18:41 +00:00
"""
Displays the list of user, who have unreturned :class:`Pinte(s) <gestion.models.Pinte>`.
"""
2018-12-23 20:21:30 +00:00
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):
2019-02-28 12:18:41 +00:00
"""
Displays a :class:`forms.gestion.GenerateReleveForm` to generate a releve.
"""
2019-01-05 23:01:30 +00:00
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
2019-01-22 19:27:18 +00:00
now = datetime.now()
2019-01-05 23:01:30 +00:00
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:
2019-01-17 22:16:43 +00:00
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"})
2019-05-03 19:09:32 +00:00
2019-06-23 08:54:21 +00:00
@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,
}
)
2019-05-03 19:09:32 +00:00
########## categories ##########
@active_required
@login_required
@permission_required('gestion.add_category')
def addCategory(request):
"""
Displays a :class:`gestion.forms.CategoryForm` to add a category.
"""
form = CategoryForm(request.POST or None)
if(form.is_valid()):
category = form.save()
messages.success(request, "La catégorie a bien été ajoutée")
return redirect(reverse('gestion:categoryProfile', kwargs={'pk':category.pk}))
return render(request, "form.html", {"form": form, "form_title": "Ajout d'une catégorie", "form_button": "Ajouter", "form_button_icon": "plus-square"})
@active_required
@login_required
@permission_required('gestion.change_category')
def editCategory(request, pk):
"""
Displays a :class:`gestion.forms.CategoryForm` to edit a category.
pk
The primary key of the the :class:`gestion.models.Category` to edit.
"""
category = get_object_or_404(Category, pk=pk)
form = CategoryForm(request.POST or None, instance=category)
if(form.is_valid()):
form.save()
messages.success(request, "La catégorie a bien été modifiée")
return redirect(reverse('gestion:categoryProfile', kwargs={'pk': category.pk}))
return render(request, "form.html", {"form": form, "form_title": "Modification d'une catégorie", "form_button": "Modifier", "form_button_icon": "pencil-alt"})
@active_required
@login_required
@permission_required('gestion.view_category')
def categoriesList(request):
"""
Display the list of :class:`categories <gestion.models.Category>`.
"""
categories = Category.objects.all().order_by('order')
return render(request, "gestion/categories_list.html", {"categories": categories})
@active_required
@login_required
@permission_required('gestion.view_category')
def searchCategory(request):
"""
Displays a :class:`gestion.forms.SearchCategory` to search a :class:`gestion.models.Category`.
"""
form = SearchCategoryForm(request.POST or None)
if(form.is_valid()):
return redirect(reverse('gestion:categoryProfile', kwargs={'pk': form.cleaned_data['category'].pk }))
return render(request, "form.html", {"form": form, "form_title":"Rechercher une catégorie", "form_button": "Rechercher", "form_button_icon": "search"})
@active_required
@login_required
@permission_required('gestion.view_category')
def categoryProfile(request, pk):
"""
Displays the profile of a :class:`gestion.models.Category`.
pk
The primary key of the :class:`gestion.models.Category` to display profile.
"""
category = get_object_or_404(Category, pk=pk)
return render(request, "gestion/category_profile.html", {"category": category})
class CategoriesAutocomplete(autocomplete.Select2QuerySetView):
"""
Autocomplete view for active :class:`categories <gestion.models.Category>`.
"""
def get_queryset(self):
qs = Category.objects.all()
if self.q:
qs = qs.filter(name__icontains=self.q)
2019-05-03 21:27:11 +00:00
return qs
@active_required
@login_required
@admin_required
def stats(request):
users = User.objects.all()
adherents = [x for x in users if x.profile.is_adherent]
transactions = ConsumptionHistory.objects.all()
categories = Category.objects.all()
categories_shown = Category.objects.exclude(order=0)
products = Product.objects.all()
active_products = Product.objects.filter(is_active=True)
active_kegs = Keg.objects.filter(is_active=True)
sum_positive_balance = sum([x.profile.balance for x in users if x.profile.balance > 0])
sum_balance = sum([x.profile.balance for x in users])
schools = School.objects.all()
groups = Group.objects.all()
admins = User.objects.filter(is_staff=True)
superusers = User.objects.filter(is_superuser=True)
menus = Menu.objects.all()
payment_methods = PaymentMethod.objects.all()
cotisations = Cotisation.objects.all()
return render(request, "gestion/stats.html", {
"users": users,
"adherents": adherents,
"transactions": transactions,
"categories": categories,
"categories_shown": categories_shown,
"products": products,
"active_products": active_products,
"active_kegs": active_kegs,
"sum_positive_balance": sum_positive_balance,
"sum_balance": sum_balance,
"schools": schools,
"groups": groups,
"admins": admins,
"superusers": superusers,
"menus": menus,
"payment_methods": payment_methods,
"cotisations": cotisations,
})