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
+
+
+
+
+ Date/Heure |
+ Par |
+ Nb articles |
+ Commande |
+
+
+
+ {% for inventory in inventories %}
+
+ {{ inventory.at }} |
+ {{ inventory.by.trigramme }} |
+ {{ inventory.nb_articles }} |
+ {{ inventory.order|default_if_none:'' }} |
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+{% 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 %}
+
+
+
+{% 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,
+ })