From ffa73c41c307c1afba2dbaf50470896fca442679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delobelle?= Date: Sat, 27 Aug 2016 14:12:01 +0200 Subject: [PATCH] =?UTF-8?q?Ajout=20du=20listing=20et=20cr=C3=A9ation=20d'i?= =?UTF-8?q?nventaires?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kfet/forms.py | 21 ++++++- kfet/models.py | 3 + kfet/static/kfet/css/index.css | 6 ++ kfet/templates/kfet/inventory.html | 52 ++++++++++++++++ kfet/templates/kfet/inventory_create.html | 41 ++++++++++++ kfet/urls.py | 9 +++ kfet/views.py | 76 +++++++++++++++++++++-- 7 files changed, 203 insertions(+), 5 deletions(-) create mode 100644 kfet/templates/kfet/inventory.html create mode 100644 kfet/templates/kfet/inventory_create.html diff --git a/kfet/forms.py b/kfet/forms.py index ea12d424..709d62ff 100644 --- a/kfet/forms.py +++ b/kfet/forms.py @@ -8,7 +8,7 @@ from django.forms.models import BaseInlineFormSet from django.utils import timezone from kfet.models import (Account, Checkout, Article, OperationGroup, Operation, CheckoutStatement, ArticleCategory, Settings, AccountNegative, Transfer, - TransferGroup, Supplier) + TransferGroup, Supplier, Inventory, InventoryArticle) from gestioncof.models import CofProfile # ----- @@ -397,3 +397,22 @@ TransferFormSet = modelformset_factory( min_num = 1, validate_min = True, extra = 9, ) + +# ----- +# Inventory forms +# ----- + +class InventoryArticleForm(forms.Form): + article = forms.ModelChoiceField( + queryset = Article.objects.all(), + widget = forms.HiddenInput(), + ) + stock_new = forms.IntegerField(required = False) + + def __init__(self, *args, **kwargs): + super(InventoryArticleForm, self).__init__(*args, **kwargs) + if 'initial' in kwargs: + self.name = kwargs['initial']['name'] + self.stock_old = kwargs['initial']['stock_old'] + self.category = kwargs['initial']['category'] + self.category_name = kwargs['initial']['category__name'] diff --git a/kfet/models.py b/kfet/models.py index 47c734a3..eaf037b6 100644 --- a/kfet/models.py +++ b/kfet/models.py @@ -356,6 +356,9 @@ class Inventory(models.Model): related_name = "inventory", blank = True, null = True, default = None) + class Meta: + ordering = ['-at'] + class InventoryArticle(models.Model): inventory = models.ForeignKey( Inventory, on_delete = models.PROTECT) diff --git a/kfet/static/kfet/css/index.css b/kfet/static/kfet/css/index.css index 72410267..8f1588cf 100644 --- a/kfet/static/kfet/css/index.css +++ b/kfet/static/kfet/css/index.css @@ -145,3 +145,9 @@ a:focus, a:hover { .content-right-block table { width:100%; } + +.content-right-block table thead { + background:#c8102e; + color:#fff; + font-weight:bold; +} diff --git a/kfet/templates/kfet/inventory.html b/kfet/templates/kfet/inventory.html new file mode 100644 index 00000000..dc1ed19d --- /dev/null +++ b/kfet/templates/kfet/inventory.html @@ -0,0 +1,52 @@ +{% extends 'kfet/base.html' %} + +{% block title %}Inventaires{% endblock %} +{% block content-header-title %}Inventaires{% endblock %} + +{% block content %} + +
+
+
+
+
+ +
+
+
+ {% include 'kfet/base_messages.html' %} +
+
+

Liste des inventaires

+
+ + + + + + + + + + + {% for inventory in inventories %} + + + + + + + {% endfor %} + +
Date/HeureParNb articlesCommande
{{ inventory.at }}{{ inventory.by.trigramme }}{{ inventory.nb_articles }}{{ inventory.order|default_if_none:'' }}
+
+
+
+
+
+ +{% endblock %} diff --git a/kfet/templates/kfet/inventory_create.html b/kfet/templates/kfet/inventory_create.html new file mode 100644 index 00000000..da06d061 --- /dev/null +++ b/kfet/templates/kfet/inventory_create.html @@ -0,0 +1,41 @@ +{% extends 'kfet/base.html' %} + +{% block title %}Nouvel inventaire{% endblock %} +{% block content-header-title %}Nouvel inventaire{% endblock %} + +{% block content %} + +
+ + + + + + + + + + {% for form in formset %} + {% ifchanged form.category %} + + + + {% endifchanged %} + + {{ form.article }} + + + + + {% endfor %} + +
ArticleThéo.Réel
{{ form.category_name }}
{{ form.name }}{{ form.stock_old }}{{ form.stock_new }}
+ {% if not perms.kfet.add_inventory %} + + {% endif %} + {% csrf_token %} + {{ formset.management_form }} + +
+ +{% endblock %} diff --git a/kfet/urls.py b/kfet/urls.py index 9a4703b5..55286d00 100644 --- a/kfet/urls.py +++ b/kfet/urls.py @@ -161,4 +161,13 @@ urlpatterns = [ name = 'kfet.transfers.create'), url(r'^transfers/perform$', views.perform_transfers, name = 'kfet.transfers.perform'), + + # ----- + # Inventories urls + + url(r'^inventaires/$', + permission_required('kfet.is_team')(views.InventoryList.as_view()), + name = 'kfet.inventory'), + url(r'^inventaires/new$', views.inventory_create, + name = 'kfet.inventory.create'), ] diff --git a/kfet/views.py b/kfet/views.py index fad87333..87dc9a12 100644 --- a/kfet/views.py +++ b/kfet/views.py @@ -2,7 +2,7 @@ from django.shortcuts import render, get_object_or_404, redirect from django.core.exceptions import PermissionDenied, ValidationError from django.core.cache import cache from django.views.generic import ListView, DetailView -from django.views.generic.edit import CreateView, UpdateView, DeleteView +from django.views.generic.edit import CreateView, UpdateView, DeleteView, FormView from django.core.urlresolvers import reverse_lazy from django.contrib import messages from django.contrib.messages.views import SuccessMessageMixin @@ -10,15 +10,16 @@ from django.contrib.auth import authenticate, login from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.models import User, Permission, Group from django.http import HttpResponse, JsonResponse, Http404 -from django.forms import modelformset_factory +from django.forms import modelformset_factory, formset_factory from django.db import IntegrityError, transaction -from django.db.models import F, Sum, Prefetch +from django.db.models import F, Sum, Prefetch, Count 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) + CheckoutStatement, GenericTeamToken, Supplier, SupplierArticle, Inventory, + InventoryArticle) from kfet.forms import * from collections import defaultdict from kfet import consumers @@ -1257,3 +1258,70 @@ def perform_transfers(request): data['transfers'].append(transfer.pk) return JsonResponse(data) + +class InventoryList(ListView): + queryset = (Inventory.objects + .select_related('by', 'order') + .annotate(nb_articles=Count('articles')) + .order_by('-at')) + template_name = 'kfet/inventory.html' + context_object_name = 'inventories' + +@permission_required('kfet.is_team') +def inventory_create(request): + + articles = (Article.objects + .select_related('category') + .order_by('category__name', 'name') + ) + initial = [] + data = [] + for article in articles: + initial.append({ + 'article' : article.pk, + 'stock_old': article.stock, + 'name' : article.name, + 'category' : article.category_id, + 'category__name': article.category.name + }) + + cls_formset = formset_factory( + form = InventoryArticleForm, + extra = 0, + ) + + if request.POST: + formset = cls_formset(request.POST, initial=initial) + if formset.is_valid(): + with transaction.atomic(): + + articles = Article.objects.select_for_update() + inventory = Inventory() + inventory.by = request.user.profile.account_kfet + saved = False + for form in formset: + if form.cleaned_data['stock_new'] is not None: + if not saved: + inventory.save() + + article = articles.get(pk=form.cleaned_data['article'].pk) + stock_old = article.stock + stock_new = form.cleaned_data['stock_new'] + stock_error = stock_new - stock_old + InventoryArticle.objects.create( + inventory = inventory, + article = article, + stock_old = stock_old, + stock_new = stock_new, + stock_error = stock_error) + article.stock = stock_new + article.save() + print('ok') + else: + messages.error('Pas marché') + else: + formset = cls_formset(initial = initial) + + return render(request, 'kfet/inventory_create.html', { + 'formset': formset, + })