Ajout livraison
- Possible de passer une livraison à un fournisseur - Proposition de quantités générées à partir des ventes sur les 5 dernières semaines - Mail généré à partir d'une commande (pas d'envoi auto) - box_capacity et box_type passe de SupplierArticle à Article
This commit is contained in:
parent
d531c7dd5b
commit
61feb9bbcd
9 changed files with 391 additions and 28 deletions
181
kfet/views.py
181
kfet/views.py
|
@ -12,19 +12,21 @@ from django.contrib.auth.models import User, Permission, Group
|
|||
from django.http import HttpResponse, JsonResponse, Http404
|
||||
from django.forms import modelformset_factory, formset_factory
|
||||
from django.db import IntegrityError, transaction
|
||||
from django.db.models import F, Sum, Prefetch, Count
|
||||
from django.db.models import F, Sum, Prefetch, Count, Func
|
||||
from django.db.models.functions import Coalesce
|
||||
from django.utils import timezone
|
||||
from django.utils.crypto import get_random_string
|
||||
from gestioncof.models import CofProfile, Clipper
|
||||
from kfet.models import (Account, Checkout, Article, Settings, AccountNegative,
|
||||
CheckoutStatement, GenericTeamToken, Supplier, SupplierArticle, Inventory,
|
||||
InventoryArticle, Order)
|
||||
InventoryArticle, Order, OrderArticle)
|
||||
from kfet.forms import *
|
||||
from collections import defaultdict
|
||||
from kfet import consumers
|
||||
import datetime
|
||||
from datetime import timedelta
|
||||
import django_cas_ng
|
||||
import heapq
|
||||
import statistics
|
||||
|
||||
@login_required
|
||||
def home(request):
|
||||
|
@ -1293,7 +1295,6 @@ def inventory_create(request):
|
|||
.order_by('category__name', 'name')
|
||||
)
|
||||
initial = []
|
||||
data = []
|
||||
for article in articles:
|
||||
initial.append({
|
||||
'article' : article.pk,
|
||||
|
@ -1324,6 +1325,7 @@ def inventory_create(request):
|
|||
if form.cleaned_data['stock_new'] is not None:
|
||||
if not saved:
|
||||
inventory.save()
|
||||
saved = True
|
||||
|
||||
article = articles.get(pk=form.cleaned_data['article'].pk)
|
||||
stock_old = article.stock
|
||||
|
@ -1356,13 +1358,182 @@ def inventory_create(request):
|
|||
class OrderList(ListView):
|
||||
model = Order
|
||||
template_name = 'kfet/order.html'
|
||||
context_object_name = 'inventories'
|
||||
context_object_name = 'orders'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(OrderList, self).get_context_data(**kwargs)
|
||||
context['suppliers'] = Supplier.objects.order_by('name')
|
||||
return context
|
||||
|
||||
@permission_required('kfet.is_team')
|
||||
def order_create(request, pk):
|
||||
supplier = Supplier.objects.get(pk=pk)
|
||||
|
||||
articles = (Article.objects
|
||||
.filter(suppliers=supplier.pk)
|
||||
.select_related('category')
|
||||
.order_by('category__name', 'name'))
|
||||
|
||||
print(articles[0].suppliers.all())
|
||||
|
||||
initial = []
|
||||
today = timezone.now().date()
|
||||
sales_q = (Operation.objects
|
||||
.select_related('group')
|
||||
.filter(article__in=articles, canceled_at=None)
|
||||
.values('article'))
|
||||
sales_s1 = (sales_q
|
||||
.filter(
|
||||
group__at__gte = today-timedelta(weeks=5),
|
||||
group__at__lt = today-timedelta(weeks=4))
|
||||
.annotate(nb=Sum('article_nb'))
|
||||
)
|
||||
sales_s1 = { d['article']:d['nb'] for d in sales_s1 }
|
||||
sales_s2 = (sales_q
|
||||
.filter(
|
||||
group__at__gte = today-timedelta(weeks=4),
|
||||
group__at__lt = today-timedelta(weeks=3))
|
||||
.annotate(nb=Sum('article_nb'))
|
||||
)
|
||||
sales_s2 = { d['article']:d['nb'] for d in sales_s2 }
|
||||
sales_s3 = (sales_q
|
||||
.filter(
|
||||
group__at__gte = today-timedelta(weeks=3),
|
||||
group__at__lt = today-timedelta(weeks=2))
|
||||
.annotate(nb=Sum('article_nb'))
|
||||
)
|
||||
sales_s3 = { d['article']:d['nb'] for d in sales_s3 }
|
||||
sales_s4 = (sales_q
|
||||
.filter(
|
||||
group__at__gte = today-timedelta(weeks=2),
|
||||
group__at__lt = today-timedelta(weeks=1))
|
||||
.annotate(nb=Sum('article_nb'))
|
||||
)
|
||||
sales_s4 = { d['article']:d['nb'] for d in sales_s4 }
|
||||
sales_s5 = (sales_q
|
||||
.filter(group__at__gte = today-timedelta(weeks=1))
|
||||
.annotate(nb=Sum('article_nb'))
|
||||
)
|
||||
sales_s5 = { d['article']:d['nb'] for d in sales_s5 }
|
||||
|
||||
for article in articles:
|
||||
v_s1 = sales_s1.get(article.pk, 0)
|
||||
v_s2 = sales_s2.get(article.pk, 0)
|
||||
v_s3 = sales_s3.get(article.pk, 0)
|
||||
v_s4 = sales_s4.get(article.pk, 0)
|
||||
v_s5 = sales_s5.get(article.pk, 0)
|
||||
v_all = [v_s1, v_s2, v_s3, v_s4, v_s5]
|
||||
v_3max = heapq.nlargest(3, v_all)
|
||||
v_moy = statistics.mean(v_3max)
|
||||
v_et = statistics.pstdev(v_3max, v_moy)
|
||||
v_prev = v_moy + v_et
|
||||
c_rec_tot = max(v_prev * 1.5 - article.stock, 0)
|
||||
if article.box_capacity:
|
||||
c_rec_temp = c_rec_tot / box_capacity
|
||||
if c_rec_temp >= 10:
|
||||
c_rec = round(c_rec_temp)
|
||||
elif c_rec_temp > 5:
|
||||
c_rec = 10
|
||||
elif c_rec_temp > 2:
|
||||
c_rec = 5
|
||||
else:
|
||||
c_rec = round(c_rec_temp)
|
||||
initial.append({
|
||||
'article': article.pk,
|
||||
'name': article.name,
|
||||
'category': article.category_id,
|
||||
'category__name': article.category.name,
|
||||
'stock': article.stock,
|
||||
'box_capacity': article.box_capacity,
|
||||
'v_s1': v_s1,
|
||||
'v_s2': v_s2,
|
||||
'v_s3': v_s3,
|
||||
'v_s4': v_s4,
|
||||
'v_s5': v_s5,
|
||||
'v_moy': round(v_moy),
|
||||
'v_et': round(v_et),
|
||||
'v_prev': round(v_prev),
|
||||
'c_rec': article.box_capacity and c_rec or round(c_rec_tot),
|
||||
})
|
||||
|
||||
cls_formset = formset_factory(
|
||||
form = OrderArticleForm,
|
||||
extra = 0)
|
||||
|
||||
if request.POST:
|
||||
formset = cls_formset(request.POST, initial=initial)
|
||||
|
||||
if not request.user.has_perm('kfet.add_order'):
|
||||
messages.error(request, 'Permission refusée')
|
||||
elif formset.is_valid():
|
||||
order = Order()
|
||||
order.supplier = supplier
|
||||
saved = False
|
||||
for form in formset:
|
||||
if form.cleaned_data['quantity_ordered'] is not None:
|
||||
if not saved:
|
||||
order.save()
|
||||
saved = True
|
||||
|
||||
article = articles.get(pk=form.cleaned_data['article'].pk)
|
||||
q_ordered = form.cleaned_data['quantity_ordered']
|
||||
if article.box_capacity:
|
||||
q_ordered /= article.box_capacity
|
||||
OrderArticle.objects.create(
|
||||
order = order,
|
||||
article = article,
|
||||
quantity_ordered = q_ordered)
|
||||
if saved:
|
||||
messages.success(request, 'Commande créée')
|
||||
return redirect('kfet.order.read', order.pk)
|
||||
messages.warning(request, 'Rien commandé => Pas de commande')
|
||||
else:
|
||||
messages.error('Corrigez les erreurs')
|
||||
else:
|
||||
formset = cls_formset(initial=initial)
|
||||
|
||||
return render(request, 'kfet/order_create.html', {
|
||||
'supplier': supplier,
|
||||
'formset' : formset,
|
||||
})
|
||||
|
||||
class OrderRead(DetailView):
|
||||
model = Order
|
||||
template_name = 'kfet/order_read.html'
|
||||
context_object_name = 'order'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(OrderRead, self).get_context_data(**kwargs)
|
||||
orderarticles = (OrderArticle.objects
|
||||
.select_related('article', 'article__category')
|
||||
.filter(order=self.object)
|
||||
.order_by('article__category__name', 'article__name')
|
||||
)
|
||||
mail = ("Bonjour,\n\nNous voudrions pour le ##DATE## à la K-Fêt de "
|
||||
"l'ENS Ulm :")
|
||||
category = 0
|
||||
for orderarticle in orderarticles:
|
||||
if category != orderarticle.article.category:
|
||||
category = orderarticle.article.category
|
||||
mail += '\n'
|
||||
nb = orderarticle.quantity_ordered
|
||||
box = ''
|
||||
if orderarticle.article.box_capacity:
|
||||
nb /= orderarticle.article.box_capacity
|
||||
if nb >= 2:
|
||||
box = ' %ss de' % orderarticle.article.box_type
|
||||
else:
|
||||
box = ' %s de' % orderarticle.article.box_type
|
||||
name = orderarticle.article.name.capitalize()
|
||||
mail += "\n- %s%s %s" % (round(nb), box, name)
|
||||
|
||||
mail += ("\n\nMerci d'appeler le numéro suivant lorsque les livreurs "
|
||||
"sont là : ##TELEPHONE##\nCordialement,\n##PRENOM## ##NOM## "
|
||||
", pour la K-Fêt de l'ENS Ulm")
|
||||
|
||||
context['mail'] = mail
|
||||
return context
|
||||
|
||||
class SupplierUpdate(SuccessMessageMixin, UpdateView):
|
||||
model = Supplier
|
||||
template_name = 'kfet/supplier_form.html'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue