From 7db497d09593bf3e5990e399bb110fd012421cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delobelle?= Date: Thu, 13 Apr 2017 16:34:29 +0200 Subject: [PATCH 1/5] Less articles prices history - Prices given with order_to_inventory are saved to db only if they are updated (it doesn't create a new price row each time) Fixes #142. --- kfet/views.py | 94 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 33 deletions(-) diff --git a/kfet/views.py b/kfet/views.py index 330b195a..a33e3fc0 100644 --- a/kfet/views.py +++ b/kfet/views.py @@ -1946,6 +1946,7 @@ class OrderRead(DetailView): context['mail'] = mail return context + @teamkfet_required def order_to_inventory(request, pk): order = get_object_or_404(Order, pk=pk) @@ -1953,28 +1954,36 @@ def order_to_inventory(request, pk): if hasattr(order, 'inventory'): raise Http404 - articles = (Article.objects - .filter(orders=order.pk) - .select_related('category') - .prefetch_related(Prefetch('orderarticle_set', - queryset = OrderArticle.objects.filter(order=order), - to_attr = 'order')) - .prefetch_related(Prefetch('supplierarticle_set', - queryset = (SupplierArticle.objects - .filter(supplier=order.supplier) - .order_by('-at')), - to_attr = 'supplier')) - .order_by('category__name', 'name')) + supplier_prefetch = Prefetch( + 'article__supplierarticle_set', + queryset=( + SupplierArticle.objects + .filter(supplier=order.supplier) + .order_by('-at') + ), + to_attr='supplier', + ) + + order_articles = ( + OrderArticle.objects + .filter(order=order.pk) + .select_related('article', 'article__category') + .prefetch_related( + supplier_prefetch, + ) + .order_by('article__category__name', 'article__name') + ) initial = [] - for article in articles: + for order_article in order_articles: + article = order_article.article initial.append({ 'article': article.pk, 'name': article.name, 'category': article.category_id, 'category__name': article.category.name, - 'quantity_ordered': article.order[0].quantity_ordered, - 'quantity_received': article.order[0].quantity_ordered, + 'quantity_ordered': order_article.quantity_ordered, + 'quantity_received': order_article.quantity_ordered, 'price_HT': article.supplier[0].price_HT, 'TVA': article.supplier[0].TVA, 'rights': article.supplier[0].rights, @@ -1989,31 +1998,50 @@ def order_to_inventory(request, pk): messages.error(request, 'Permission refusée') elif formset.is_valid(): with transaction.atomic(): - inventory = Inventory() - inventory.order = order - inventory.by = request.user.profile.account_kfet - inventory.save() + inventory = Inventory.objects.create( + order=order, by=request.user.profile.account_kfet, + ) + new_supplierarticle = [] + new_inventoryarticle = [] for form in formset: q_received = form.cleaned_data['quantity_received'] article = form.cleaned_data['article'] - SupplierArticle.objects.create( - supplier = order.supplier, - article = article, - price_HT = form.cleaned_data['price_HT'], - TVA = form.cleaned_data['TVA'], - rights = form.cleaned_data['rights']) - (OrderArticle.objects - .filter(order=order, article=article) - .update(quantity_received = q_received)) - InventoryArticle.objects.create( - inventory = inventory, - article = article, - stock_old = article.stock, - stock_new = article.stock + q_received) + + price_HT = form.cleaned_data['price_HT'] + TVA = form.cleaned_data['TVA'] + rights = form.cleaned_data['rights'] + + if any((form.initial['price_HT'] != price_HT, + form.initial['TVA'] != TVA, + form.initial['rights'] != rights)): + new_supplierarticle.append( + SupplierArticle( + supplier=order.supplier, + article=article, + price_HT=price_HT, + TVA=TVA, + rights=rights, + ) + ) + ( + OrderArticle.objects + .filter(order=order, article=article) + .update(quantity_received=q_received) + ) + new_inventoryarticle.append( + InventoryArticle( + inventory=inventory, + article=article, + stock_old=article.stock, + stock_new=article.stock + q_received, + ) + ) article.stock += q_received if q_received > 0: article.is_sold = True article.save() + SupplierArticle.objects.bulk_create(new_supplierarticle) + InventoryArticle.objects.bulk_create(new_inventoryarticle) messages.success(request, "C'est tout bon !") return redirect('kfet.order') else: From 2aee43e01a67d07f0392f230d83f6e5db10f2de7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Mon, 24 Apr 2017 21:27:01 +0100 Subject: [PATCH 2/5] Add more configuration options for redis - `REDIS_HOST` can be specified in the secrets - Two new secrets: `REDIS_PASSWD` and `REDIS_DB` --- cof/settings/common.py | 8 ++++++-- cof/settings/secret_example.py | 3 +++ provisioning/bootstrap.sh | 10 +++++----- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/cof/settings/common.py b/cof/settings/common.py index 93b11dae..612d52fc 100644 --- a/cof/settings/common.py +++ b/cof/settings/common.py @@ -22,7 +22,8 @@ except KeyError: # Other secrets try: from .secret import ( - SECRET_KEY, RECAPTCHA_PUBLIC_KEY, RECAPTCHA_PRIVATE_KEY, ADMINS + SECRET_KEY, RECAPTCHA_PUBLIC_KEY, RECAPTCHA_PRIVATE_KEY, ADMINS, + REDIS_PASSWD, REDIS_DB, REDIS_HOST ) except ImportError: raise RuntimeError("Secrets missing") @@ -159,7 +160,10 @@ CHANNEL_LAYERS = { "default": { "BACKEND": "asgi_redis.RedisChannelLayer", "CONFIG": { - "hosts": [(os.environ.get("REDIS_HOST", "localhost"), 6379)], + "hosts": [( + "redis://:{}@{}:6379/{}" + .format(REDIS_PASSWD, REDIS_HOST, REDIS_DB) + )], }, "ROUTING": "cof.routing.channel_routing", } diff --git a/cof/settings/secret_example.py b/cof/settings/secret_example.py index 36a8e932..3dc5de4b 100644 --- a/cof/settings/secret_example.py +++ b/cof/settings/secret_example.py @@ -1,4 +1,7 @@ SECRET_KEY = 'q()(zn4m63i%5cp4)f+ww4-28_w+ly3q9=6imw2ciu&_(5_4ah' RECAPTCHA_PUBLIC_KEY = "DUMMY" RECAPTCHA_PRIVATE_KEY = "DUMMY" +REDIS_PASSWD = "dummy" +REDIS_DB = 0 +REDIS_HOST = "127.0.0.1" ADMINS = None diff --git a/provisioning/bootstrap.sh b/provisioning/bootstrap.sh index c8f73ab6..33ae8308 100644 --- a/provisioning/bootstrap.sh +++ b/provisioning/bootstrap.sh @@ -23,6 +23,9 @@ apt-get install -y mysql-server mysql -uroot -p$DBPASSWD -e "CREATE DATABASE $DBNAME; GRANT ALL PRIVILEGES ON $DBNAME.* TO '$DBUSER'@'localhost' IDENTIFIED BY '$DBPASSWD'" mysql -uroot -p$DBPASSWD -e "GRANT ALL PRIVILEGES ON test_$DBNAME.* TO '$DBUSER'@'localhost'" +# Configuration de redis +echo "requirepass dummy" >> /etc/redis/redis.conf + # Installation et configuration d'Apache apt-get install -y apache2 a2enmod proxy proxy_http proxy_wstunnel headers @@ -36,7 +39,7 @@ chown -R ubuntu:www-data /var/www/static # Mise en place du .bash_profile pour tout configurer lors du `vagrant ssh` cat >> ~ubuntu/.bashrc < Date: Mon, 24 Apr 2017 21:52:40 +0100 Subject: [PATCH 3/5] Fix settings in the provisioning script --- provisioning/bootstrap.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/provisioning/bootstrap.sh b/provisioning/bootstrap.sh index 33ae8308..1e576a65 100644 --- a/provisioning/bootstrap.sh +++ b/provisioning/bootstrap.sh @@ -25,6 +25,7 @@ mysql -uroot -p$DBPASSWD -e "GRANT ALL PRIVILEGES ON test_$DBNAME.* TO '$DBUSER' # Configuration de redis echo "requirepass dummy" >> /etc/redis/redis.conf +service redis restart # Installation et configuration d'Apache apt-get install -y apache2 @@ -39,7 +40,7 @@ chown -R ubuntu:www-data /var/www/static # Mise en place du .bash_profile pour tout configurer lors du `vagrant ssh` cat >> ~ubuntu/.bashrc < Date: Tue, 25 Apr 2017 20:23:21 +0100 Subject: [PATCH 4/5] Add REDIS_PORT to the settings and secrets --- cof/settings/common.py | 7 ++++--- cof/settings/secret_example.py | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cof/settings/common.py b/cof/settings/common.py index 612d52fc..261760d6 100644 --- a/cof/settings/common.py +++ b/cof/settings/common.py @@ -23,7 +23,7 @@ except KeyError: try: from .secret import ( SECRET_KEY, RECAPTCHA_PUBLIC_KEY, RECAPTCHA_PRIVATE_KEY, ADMINS, - REDIS_PASSWD, REDIS_DB, REDIS_HOST + REDIS_PASSWD, REDIS_DB, REDIS_HOST, REDIS_PORT ) except ImportError: raise RuntimeError("Secrets missing") @@ -161,8 +161,9 @@ CHANNEL_LAYERS = { "BACKEND": "asgi_redis.RedisChannelLayer", "CONFIG": { "hosts": [( - "redis://:{}@{}:6379/{}" - .format(REDIS_PASSWD, REDIS_HOST, REDIS_DB) + "redis://:{passwd}@{host}:{port}/{db}" + .format(passwd=REDIS_PASSWD, host=REDIS_HOST, + port=REDIS_PORT, db=REDIS_DB) )], }, "ROUTING": "cof.routing.channel_routing", diff --git a/cof/settings/secret_example.py b/cof/settings/secret_example.py index 3dc5de4b..eeb5271c 100644 --- a/cof/settings/secret_example.py +++ b/cof/settings/secret_example.py @@ -2,6 +2,7 @@ SECRET_KEY = 'q()(zn4m63i%5cp4)f+ww4-28_w+ly3q9=6imw2ciu&_(5_4ah' RECAPTCHA_PUBLIC_KEY = "DUMMY" RECAPTCHA_PRIVATE_KEY = "DUMMY" REDIS_PASSWD = "dummy" +REDIS_PORT = 6379 REDIS_DB = 0 REDIS_HOST = "127.0.0.1" ADMINS = None From fb4258f821b20db969935d55dcff55d112b842eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Tue, 25 Apr 2017 20:23:51 +0100 Subject: [PATCH 5/5] Set the redis passwd properly in bootstrap.sh --- provisioning/bootstrap.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/provisioning/bootstrap.sh b/provisioning/bootstrap.sh index 1e576a65..38efdfb5 100644 --- a/provisioning/bootstrap.sh +++ b/provisioning/bootstrap.sh @@ -24,8 +24,9 @@ mysql -uroot -p$DBPASSWD -e "CREATE DATABASE $DBNAME; GRANT ALL PRIVILEGES ON $D mysql -uroot -p$DBPASSWD -e "GRANT ALL PRIVILEGES ON test_$DBNAME.* TO '$DBUSER'@'localhost'" # Configuration de redis -echo "requirepass dummy" >> /etc/redis/redis.conf -service redis restart +REDIS_PASSWD="dummy" +redis-cli CONFIG SET requirepass $REDIS_PASSWD +redis-cli -a $REDIS_PASSWD CONFIG REWRITE # Installation et configuration d'Apache apt-get install -y apache2