From 8f88f7cb70dd9b23629468e2e58e33281de586a3 Mon Sep 17 00:00:00 2001 From: guillaume-renaud Date: Tue, 3 Jan 2017 14:50:49 +0100 Subject: [PATCH] Take item from stock form addition --- counter/views.py | 23 ++-- locale/fr/LC_MESSAGES/django.po | 108 +++++++++++-------- stock/templates/stock/stock_take_items.jinja | 17 +++ stock/urls.py | 1 + stock/views.py | 84 ++++++++++++++- 5 files changed, 175 insertions(+), 58 deletions(-) create mode 100644 stock/templates/stock/stock_take_items.jinja diff --git a/counter/views.py b/counter/views.py index 4678fd44..22f4e7fb 100644 --- a/counter/views.py +++ b/counter/views.py @@ -69,29 +69,36 @@ class RefillForm(forms.ModelForm): class CounterTabsMixin(TabedViewMixin): def get_tabs_title(self): - return self.object + if hasattr(self.object, 'stock_owner') : + return self.object.stock_owner.counter + else: + return self.object def get_list_of_tabs(self): tab_list = [] tab_list.append({ - 'url': reverse_lazy('counter:details', kwargs={'counter_id': self.object.id}), + 'url': reverse_lazy('counter:details', + kwargs={'counter_id': self.object.stock_owner.counter.id if hasattr(self.object, 'stock_owner') else self.object.id }), 'slug': 'counter', 'name': _("Counter"), }) - if self.object.type == "BAR": + if self.object.stock_owner.counter.type if hasattr(self.object, 'stock_owner') else self.object.type == "BAR": tab_list.append({ - 'url': reverse_lazy('counter:cash_summary', kwargs={'counter_id': self.object.id}), + 'url': reverse_lazy('counter:cash_summary', + kwargs={'counter_id': self.object.stock_owner.counter.id if hasattr(self.object, 'stock_owner') else self.object.id}), 'slug': 'cash_summary', 'name': _("Cash summary"), }) tab_list.append({ - 'url': reverse_lazy('counter:last_ops', kwargs={'counter_id': self.object.id}), + 'url': reverse_lazy('counter:last_ops', + kwargs={'counter_id': self.object.stock_owner.counter.id if hasattr(self.object, 'stock_owner') else self.object.id}), 'slug': 'last_ops', 'name': _("Last operations"), }) tab_list.append({ - 'url': reverse_lazy('stock:items_list', kwargs={'stock_id': self.object.stock.id}), - 'slug': 'stock_items_list', - 'name': _("Stock items list"), + 'url': reverse_lazy('stock:take_items', + kwargs={'stock_id': self.object.stock.id if hasattr(self.object, 'stock') else self.object.stock_owner.id}), + 'slug': 'take_items_from_stock', + 'name': _("Take items from stock"), }) return tab_list diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index b868605f..2df6d543 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-12-29 18:13+0100\n" +"POT-Creation-Date: 2017-01-03 14:35+0100\n" "PO-Revision-Date: 2016-07-18\n" "Last-Translator: Skia \n" "Language-Team: AE info \n" @@ -519,10 +519,10 @@ msgstr "Nature" #: accounting/templates/accounting/journal_details.jinja:36 #: stock/templates/stock/stock_shopping_list.jinja:50 msgid "Done" -msgstr "Effectué" +msgstr "Effectuées" #: accounting/templates/accounting/journal_details.jinja:37 -#: counter/templates/counter/cash_summary_list.jinja:37 counter/views.py:721 +#: counter/templates/counter/cash_summary_list.jinja:37 counter/views.py:728 msgid "Comment" msgstr "Commentaire" @@ -783,7 +783,7 @@ msgstr "Total : " #: club/templates/club/club_sellings.jinja:20 club/views.py:167 #: core/templates/core/user_account_detail.jinja:18 #: core/templates/core/user_account_detail.jinja:51 -#: counter/templates/counter/cash_summary_list.jinja:33 counter/views.py:78 +#: counter/templates/counter/cash_summary_list.jinja:33 counter/views.py:82 msgid "Counter" msgstr "Comptoir" @@ -870,16 +870,16 @@ msgstr "Choisir un utilisateur" msgid "You do not have the permission to do that" msgstr "Vous n'avez pas la permission de faire cela" -#: club/views.py:165 counter/views.py:919 +#: club/views.py:165 counter/views.py:926 msgid "Begin date" msgstr "Date de début" -#: club/views.py:166 counter/views.py:920 +#: club/views.py:166 counter/views.py:927 msgid "End date" msgstr "Date de fin" #: club/views.py:180 core/templates/core/user_stats.jinja:27 -#: counter/views.py:1000 +#: counter/views.py:1007 msgid "Product" msgstr "Produit" @@ -1826,7 +1826,7 @@ msgstr "Rechargements" msgid "Eboutic invoices" msgstr "Facture eboutic" -#: core/templates/core/user_account.jinja:53 counter/views.py:489 +#: core/templates/core/user_account.jinja:53 counter/views.py:496 msgid "Etickets" msgstr "Etickets" @@ -2003,8 +2003,8 @@ msgstr "Fusionner deux utilisateurs" msgid "Subscriptions" msgstr "Cotisations" -#: core/templates/core/user_tools.jinja:24 counter/views.py:459 -#: counter/views.py:608 +#: core/templates/core/user_tools.jinja:24 counter/views.py:466 +#: counter/views.py:615 msgid "Counters" msgstr "Comptoirs" @@ -2025,7 +2025,7 @@ msgid "Product types management" msgstr "Gestion des types de produit" #: core/templates/core/user_tools.jinja:31 -#: counter/templates/counter/cash_summary_list.jinja:23 counter/views.py:479 +#: counter/templates/counter/cash_summary_list.jinja:23 counter/views.py:486 msgid "Cash register summaries" msgstr "Relevés de caisse" @@ -2377,7 +2377,7 @@ msgstr "Liste des relevés de caisse" msgid "Theoric sums" msgstr "Sommes théoriques" -#: counter/templates/counter/cash_summary_list.jinja:36 counter/views.py:722 +#: counter/templates/counter/cash_summary_list.jinja:36 counter/views.py:729 msgid "Emptied" msgstr "Coffre vidé" @@ -2501,7 +2501,7 @@ msgstr "Nouveau eticket" msgid "There is no eticket in this website." msgstr "Il n'y a pas de eticket sur ce site web." -#: counter/templates/counter/invoices_call.jinja:4 counter/views.py:484 +#: counter/templates/counter/invoices_call.jinja:4 counter/views.py:491 msgid "Invoices call" msgstr "Appels à facture" @@ -2577,121 +2577,121 @@ msgstr "Pourcentage" msgid "User not found" msgstr "Utilisateur non trouvé" -#: counter/views.py:84 +#: counter/views.py:89 msgid "Cash summary" msgstr "Relevé de caisse" -#: counter/views.py:89 +#: counter/views.py:95 msgid "Last operations" msgstr "Dernières opérations" -#: counter/views.py:94 -msgid "Stock items list" -msgstr "Liste des éléments du stock" +#: counter/views.py:101 +msgid "Take items from stock" +msgstr "" -#: counter/views.py:128 +#: counter/views.py:135 msgid "Bad credentials" msgstr "Mauvais identifiants" -#: counter/views.py:130 +#: counter/views.py:137 msgid "User is not barman" msgstr "L'utilisateur n'est pas barman." -#: counter/views.py:134 +#: counter/views.py:141 msgid "Bad location, someone is already logged in somewhere else" msgstr "Mauvais comptoir, quelqu'un est déjà connecté ailleurs" -#: counter/views.py:324 +#: counter/views.py:331 msgid "END" msgstr "FIN" -#: counter/views.py:326 +#: counter/views.py:333 msgid "CAN" msgstr "ANN" -#: counter/views.py:356 +#: counter/views.py:363 msgid "You have not enough money to buy all the basket" msgstr "Vous n'avez pas assez d'argent pour acheter le panier" -#: counter/views.py:449 +#: counter/views.py:456 msgid "Counter administration" msgstr "Administration des comptoirs" -#: counter/views.py:454 +#: counter/views.py:461 msgid "Stocks" msgstr "" -#: counter/views.py:464 +#: counter/views.py:471 msgid "Products" msgstr "Produits" -#: counter/views.py:469 +#: counter/views.py:476 msgid "Archived products" msgstr "Produits archivés" -#: counter/views.py:474 +#: counter/views.py:481 msgid "Product types" msgstr "Types de produit" -#: counter/views.py:605 +#: counter/views.py:612 msgid "Parent product" msgstr "Produit parent" -#: counter/views.py:606 +#: counter/views.py:613 msgid "Buying groups" msgstr "Groupes d'achat" -#: counter/views.py:701 +#: counter/views.py:708 msgid "10 cents" msgstr "10 centimes" -#: counter/views.py:702 +#: counter/views.py:709 msgid "20 cents" msgstr "20 centimes" -#: counter/views.py:703 +#: counter/views.py:710 msgid "50 cents" msgstr "50 centimes" -#: counter/views.py:704 +#: counter/views.py:711 msgid "1 euro" msgstr "1 €" -#: counter/views.py:705 +#: counter/views.py:712 msgid "2 euros" msgstr "2 €" -#: counter/views.py:706 +#: counter/views.py:713 msgid "5 euros" msgstr "5 €" -#: counter/views.py:707 +#: counter/views.py:714 msgid "10 euros" msgstr "10 €" -#: counter/views.py:708 +#: counter/views.py:715 msgid "20 euros" msgstr "20 €" -#: counter/views.py:709 +#: counter/views.py:716 msgid "50 euros" msgstr "50 €" -#: counter/views.py:710 +#: counter/views.py:717 msgid "100 euros" msgstr "100 €" -#: counter/views.py:711 counter/views.py:713 counter/views.py:715 -#: counter/views.py:717 counter/views.py:719 +#: counter/views.py:718 counter/views.py:720 counter/views.py:722 +#: counter/views.py:724 counter/views.py:726 msgid "Check amount" msgstr "Montant du chèque" -#: counter/views.py:712 counter/views.py:714 counter/views.py:716 -#: counter/views.py:718 counter/views.py:720 +#: counter/views.py:719 counter/views.py:721 counter/views.py:723 +#: counter/views.py:725 counter/views.py:727 msgid "Check quantity" msgstr "Nombre de chèque" -#: counter/views.py:1071 +#: counter/views.py:1078 msgid "people(s)" msgstr "personne(s)" @@ -3196,8 +3196,21 @@ msgstr "Marquer comme effectué(e)" msgid "Mark as to do" msgstr "Marquer comme à faire" +#: stock/templates/stock/stock_take_items.jinja:5 +#: stock/templates/stock/stock_take_items.jinja:9 +#, python-format +msgid "Take items form %(s)s" +msgstr "" + +#: stock/templates/stock/stock_take_items.jinja:14 +#, fuzzy +#| msgid "Take picture" +msgid "Take items" +msgstr "Prendre une photo" + #: stock/templates/stock/update_after_shopping.jinja:4 #: stock/templates/stock/update_after_shopping.jinja:8 +#, python-format msgid "Update %(s)s's quantity after shopping" msgstr "Mise à jour des stocks selon les quantités achetées pour %(s)s" @@ -3245,3 +3258,6 @@ msgstr "Un utilisateur avec cette adresse email existe déjà" msgid "You must either choose an existing user or create a new one properly" msgstr "" "Vous devez soit choisir un utilisateur existant, ou en créer un proprement." + +#~ msgid "Stock items list" +#~ msgstr "Liste des éléments du stock" diff --git a/stock/templates/stock/stock_take_items.jinja b/stock/templates/stock/stock_take_items.jinja new file mode 100644 index 00000000..f61a2d09 --- /dev/null +++ b/stock/templates/stock/stock_take_items.jinja @@ -0,0 +1,17 @@ +{% extends "core/base.jinja" %} +{% from 'core/macros.jinja' import user_profile_link %} + +{% block title %} +{% trans s = stock %}Take items form {{ s }}{% endtrans %} +{% endblock %} + +{% block content %} +

{% trans s = stock %}Take items form {{ s }}{% endtrans %}

+
+
+ {% csrf_token %} + {{ form.as_p() }} +

+
+
+{% endblock %} diff --git a/stock/urls.py b/stock/urls.py index 7a84cf99..b7744e45 100644 --- a/stock/urls.py +++ b/stock/urls.py @@ -12,6 +12,7 @@ urlpatterns = [ url(r'^(?P[0-9]+)$', StockItemList.as_view(), name='items_list'), url(r'^(?P[0-9]+)/stockItem/newItem$', StockItemCreateView.as_view(), name='new_item'), url(r'^stockItem/(?P[0-9]+)/edit$', StockItemEditView.as_view(), name='edit_item'), + url(r'^(?P[0-9]+)/stockItem/takeItems$', StockTakeItemsBaseFormView.as_view(), name='take_items'), # ShoppingList urls url(r'^(?P[0-9]+)/shoppingList/list$', StockShoppingListView.as_view(), name='shoppinglist_list'), diff --git a/stock/views.py b/stock/views.py index 44735e4e..2acfb50c 100644 --- a/stock/views.py +++ b/stock/views.py @@ -8,10 +8,9 @@ from django.forms.models import modelform_factory from django.core.urlresolvers import reverse_lazy, reverse from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin, TabedViewMixin -from counter.views import CounterAdminTabsMixin -from counter.models import Counter -from stock.models import Stock, StockItem - +from counter.views import CounterAdminTabsMixin, CounterTabsMixin +from counter.models import Counter, ProductType +from stock.models import Stock, StockItem, ShoppingList class StockItemList(CounterAdminTabsMixin, CanCreateMixin, ListView): @@ -23,6 +22,9 @@ class StockItemList(CounterAdminTabsMixin, CanCreateMixin, ListView): pk_url_kwarg = "stock_id" current_tab = "stocks" + #def can_be_viewed_by(self, user): + #return user.is_in_group(settings.SITH_GROUPS['counter-admin'].id) + class StockListView(CounterAdminTabsMixin, CanViewMixin, ListView): """ A list view for the admins @@ -357,3 +359,77 @@ class StockUpdateAfterShopppingBaseFormView(CounterAdminTabsMixin, CanEditMixin, def get_success_url(self): self.kwargs.pop('shoppinglist_id', None) return reverse_lazy('stock:shoppinglist_list', args=self.args, kwargs=self.kwargs) + + +class StockTakeItemsForm(forms.BaseForm): + """ + docstring for StockTakeItemsFormView + """ + def clean(self): + with transaction.atomic(): + for k,t in self.cleaned_data.items(): + item_id = int(k[5:]) + if int(t) > 0 : + item = StockItem.objects.filter(id=item_id).first() + item.effective_quantity -= int(t) + item.save() + return self.cleaned_data + + +class StockTakeItemsBaseFormView(CounterTabsMixin, CanEditMixin, DetailView, BaseFormView): + """ + docstring for StockTakeItemsBaseFormView + """ + model = StockItem + template_name = "stock/stock_take_items.jinja" + pk_url_kwarg = "stock_id" + current_tab = "take_items_from_stock" + + def get_form_class(self): + fields = OrderedDict() + kwargs = {} + for t in ProductType.objects.order_by('name').all(): + for i in self.stock.items.filter(type=t).order_by('name').all(): + field_name = "item-%s" % (str(i.id)) + fields[field_name] = forms.CharField(max_length=30, required=True, label=str(i)) + kwargs[field_name] = i.effective_quantity + kwargs['stock_id'] = self.stock.id + kwargs['counter_id'] = self.stock.counter.id + kwargs['base_fields'] = fields + return type('StockTakeItemsForm', (StockTakeItemsForm,), kwargs) + + def get(self, request, *args, **kwargs): + """ + Simple get view + """ + self.stock = Stock.objects.filter(id=self.kwargs['stock_id']).first() + return super(StockTakeItemsBaseFormView, self).get(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + """ + Handle the many possibilities of the post request + """ + self.object = self.get_object() + self.stock = Stock.objects.filter(id=self.kwargs['stock_id']).first() + if self.stock.counter.type == "BAR" and not ('counter_token' in self.request.session.keys() and + self.request.session['counter_token'] == self.stock.counter.token): # Also check the token to avoid the bar to be stolen + return HttpResponseRedirect(reverse_lazy('counter:details', args=self.args, + kwargs={'counter_id': self.stock.counter.id})+'?bad_location') + return super(StockTakeItemsBaseFormView, self).post(request, *args, **kwargs) + + def form_valid(self, form): + return super(StockTakeItemsBaseFormView, self).form_valid(form) + + def get_context_data(self, **kwargs): + kwargs = super(StockTakeItemsBaseFormView, self).get_context_data(**kwargs) + if 'form' not in kwargs.keys(): + kwargs['form'] = self.get_form() + kwargs['stock'] = self.stock + kwargs['counter'] = self.stock.counter + return kwargs + + def get_success_url(self): + stock = Stock.objects.filter(id=self.kwargs['stock_id']).first() + self.kwargs['counter_id'] = stock.counter.id + self.kwargs.pop('stock_id', None) + return reverse_lazy('counter:details', args=self.args, kwargs=self.kwargs)