Take item from stock form addition

This commit is contained in:
guillaume-renaud 2017-01-03 14:50:49 +01:00
parent 2f721592f1
commit 8f88f7cb70
5 changed files with 175 additions and 58 deletions

View File

@ -69,29 +69,36 @@ class RefillForm(forms.ModelForm):
class CounterTabsMixin(TabedViewMixin): class CounterTabsMixin(TabedViewMixin):
def get_tabs_title(self): def get_tabs_title(self):
if hasattr(self.object, 'stock_owner') :
return self.object.stock_owner.counter
else:
return self.object return self.object
def get_list_of_tabs(self): def get_list_of_tabs(self):
tab_list = [] tab_list = []
tab_list.append({ 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', 'slug': 'counter',
'name': _("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({ 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', 'slug': 'cash_summary',
'name': _("Cash summary"), 'name': _("Cash summary"),
}) })
tab_list.append({ 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', 'slug': 'last_ops',
'name': _("Last operations"), 'name': _("Last operations"),
}) })
tab_list.append({ tab_list.append({
'url': reverse_lazy('stock:items_list', kwargs={'stock_id': self.object.stock.id}), 'url': reverse_lazy('stock:take_items',
'slug': 'stock_items_list', kwargs={'stock_id': self.object.stock.id if hasattr(self.object, 'stock') else self.object.stock_owner.id}),
'name': _("Stock items list"), 'slug': 'take_items_from_stock',
'name': _("Take items from stock"),
}) })
return tab_list return tab_list

View File

@ -6,7 +6,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Report-Msgid-Bugs-To: \n" "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" "PO-Revision-Date: 2016-07-18\n"
"Last-Translator: Skia <skia@libskia.so>\n" "Last-Translator: Skia <skia@libskia.so>\n"
"Language-Team: AE info <ae.info@utbm.fr>\n" "Language-Team: AE info <ae.info@utbm.fr>\n"
@ -519,10 +519,10 @@ msgstr "Nature"
#: accounting/templates/accounting/journal_details.jinja:36 #: accounting/templates/accounting/journal_details.jinja:36
#: stock/templates/stock/stock_shopping_list.jinja:50 #: stock/templates/stock/stock_shopping_list.jinja:50
msgid "Done" msgid "Done"
msgstr "Effectué" msgstr "Effectuées"
#: accounting/templates/accounting/journal_details.jinja:37 #: 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" msgid "Comment"
msgstr "Commentaire" msgstr "Commentaire"
@ -783,7 +783,7 @@ msgstr "Total : "
#: club/templates/club/club_sellings.jinja:20 club/views.py:167 #: 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:18
#: core/templates/core/user_account_detail.jinja:51 #: 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" msgid "Counter"
msgstr "Comptoir" msgstr "Comptoir"
@ -870,16 +870,16 @@ msgstr "Choisir un utilisateur"
msgid "You do not have the permission to do that" msgid "You do not have the permission to do that"
msgstr "Vous n'avez pas la permission de faire cela" 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" msgid "Begin date"
msgstr "Date de début" msgstr "Date de début"
#: club/views.py:166 counter/views.py:920 #: club/views.py:166 counter/views.py:927
msgid "End date" msgid "End date"
msgstr "Date de fin" msgstr "Date de fin"
#: club/views.py:180 core/templates/core/user_stats.jinja:27 #: club/views.py:180 core/templates/core/user_stats.jinja:27
#: counter/views.py:1000 #: counter/views.py:1007
msgid "Product" msgid "Product"
msgstr "Produit" msgstr "Produit"
@ -1826,7 +1826,7 @@ msgstr "Rechargements"
msgid "Eboutic invoices" msgid "Eboutic invoices"
msgstr "Facture eboutic" 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" msgid "Etickets"
msgstr "Etickets" msgstr "Etickets"
@ -2003,8 +2003,8 @@ msgstr "Fusionner deux utilisateurs"
msgid "Subscriptions" msgid "Subscriptions"
msgstr "Cotisations" msgstr "Cotisations"
#: core/templates/core/user_tools.jinja:24 counter/views.py:459 #: core/templates/core/user_tools.jinja:24 counter/views.py:466
#: counter/views.py:608 #: counter/views.py:615
msgid "Counters" msgid "Counters"
msgstr "Comptoirs" msgstr "Comptoirs"
@ -2025,7 +2025,7 @@ msgid "Product types management"
msgstr "Gestion des types de produit" msgstr "Gestion des types de produit"
#: core/templates/core/user_tools.jinja:31 #: 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" msgid "Cash register summaries"
msgstr "Relevés de caisse" msgstr "Relevés de caisse"
@ -2377,7 +2377,7 @@ msgstr "Liste des relevés de caisse"
msgid "Theoric sums" msgid "Theoric sums"
msgstr "Sommes théoriques" 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" msgid "Emptied"
msgstr "Coffre vidé" msgstr "Coffre vidé"
@ -2501,7 +2501,7 @@ msgstr "Nouveau eticket"
msgid "There is no eticket in this website." msgid "There is no eticket in this website."
msgstr "Il n'y a pas de eticket sur ce site web." 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" msgid "Invoices call"
msgstr "Appels à facture" msgstr "Appels à facture"
@ -2577,121 +2577,121 @@ msgstr "Pourcentage"
msgid "User not found" msgid "User not found"
msgstr "Utilisateur non trouvé" msgstr "Utilisateur non trouvé"
#: counter/views.py:84 #: counter/views.py:89
msgid "Cash summary" msgid "Cash summary"
msgstr "Relevé de caisse" msgstr "Relevé de caisse"
#: counter/views.py:89 #: counter/views.py:95
msgid "Last operations" msgid "Last operations"
msgstr "Dernières opérations" msgstr "Dernières opérations"
#: counter/views.py:94 #: counter/views.py:101
msgid "Stock items list" msgid "Take items from stock"
msgstr "Liste des éléments du stock" msgstr ""
#: counter/views.py:128 #: counter/views.py:135
msgid "Bad credentials" msgid "Bad credentials"
msgstr "Mauvais identifiants" msgstr "Mauvais identifiants"
#: counter/views.py:130 #: counter/views.py:137
msgid "User is not barman" msgid "User is not barman"
msgstr "L'utilisateur n'est pas 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" msgid "Bad location, someone is already logged in somewhere else"
msgstr "Mauvais comptoir, quelqu'un est déjà connecté ailleurs" msgstr "Mauvais comptoir, quelqu'un est déjà connecté ailleurs"
#: counter/views.py:324 #: counter/views.py:331
msgid "END" msgid "END"
msgstr "FIN" msgstr "FIN"
#: counter/views.py:326 #: counter/views.py:333
msgid "CAN" msgid "CAN"
msgstr "ANN" msgstr "ANN"
#: counter/views.py:356 #: counter/views.py:363
msgid "You have not enough money to buy all the basket" msgid "You have not enough money to buy all the basket"
msgstr "Vous n'avez pas assez d'argent pour acheter le panier" msgstr "Vous n'avez pas assez d'argent pour acheter le panier"
#: counter/views.py:449 #: counter/views.py:456
msgid "Counter administration" msgid "Counter administration"
msgstr "Administration des comptoirs" msgstr "Administration des comptoirs"
#: counter/views.py:454 #: counter/views.py:461
msgid "Stocks" msgid "Stocks"
msgstr "" msgstr ""
#: counter/views.py:464 #: counter/views.py:471
msgid "Products" msgid "Products"
msgstr "Produits" msgstr "Produits"
#: counter/views.py:469 #: counter/views.py:476
msgid "Archived products" msgid "Archived products"
msgstr "Produits archivés" msgstr "Produits archivés"
#: counter/views.py:474 #: counter/views.py:481
msgid "Product types" msgid "Product types"
msgstr "Types de produit" msgstr "Types de produit"
#: counter/views.py:605 #: counter/views.py:612
msgid "Parent product" msgid "Parent product"
msgstr "Produit parent" msgstr "Produit parent"
#: counter/views.py:606 #: counter/views.py:613
msgid "Buying groups" msgid "Buying groups"
msgstr "Groupes d'achat" msgstr "Groupes d'achat"
#: counter/views.py:701 #: counter/views.py:708
msgid "10 cents" msgid "10 cents"
msgstr "10 centimes" msgstr "10 centimes"
#: counter/views.py:702 #: counter/views.py:709
msgid "20 cents" msgid "20 cents"
msgstr "20 centimes" msgstr "20 centimes"
#: counter/views.py:703 #: counter/views.py:710
msgid "50 cents" msgid "50 cents"
msgstr "50 centimes" msgstr "50 centimes"
#: counter/views.py:704 #: counter/views.py:711
msgid "1 euro" msgid "1 euro"
msgstr "1 €" msgstr "1 €"
#: counter/views.py:705 #: counter/views.py:712
msgid "2 euros" msgid "2 euros"
msgstr "2 €" msgstr "2 €"
#: counter/views.py:706 #: counter/views.py:713
msgid "5 euros" msgid "5 euros"
msgstr "5 €" msgstr "5 €"
#: counter/views.py:707 #: counter/views.py:714
msgid "10 euros" msgid "10 euros"
msgstr "10 €" msgstr "10 €"
#: counter/views.py:708 #: counter/views.py:715
msgid "20 euros" msgid "20 euros"
msgstr "20 €" msgstr "20 €"
#: counter/views.py:709 #: counter/views.py:716
msgid "50 euros" msgid "50 euros"
msgstr "50 €" msgstr "50 €"
#: counter/views.py:710 #: counter/views.py:717
msgid "100 euros" msgid "100 euros"
msgstr "100 €" msgstr "100 €"
#: counter/views.py:711 counter/views.py:713 counter/views.py:715 #: counter/views.py:718 counter/views.py:720 counter/views.py:722
#: counter/views.py:717 counter/views.py:719 #: counter/views.py:724 counter/views.py:726
msgid "Check amount" msgid "Check amount"
msgstr "Montant du chèque" msgstr "Montant du chèque"
#: counter/views.py:712 counter/views.py:714 counter/views.py:716 #: counter/views.py:719 counter/views.py:721 counter/views.py:723
#: counter/views.py:718 counter/views.py:720 #: counter/views.py:725 counter/views.py:727
msgid "Check quantity" msgid "Check quantity"
msgstr "Nombre de chèque" msgstr "Nombre de chèque"
#: counter/views.py:1071 #: counter/views.py:1078
msgid "people(s)" msgid "people(s)"
msgstr "personne(s)" msgstr "personne(s)"
@ -3196,8 +3196,21 @@ msgstr "Marquer comme effectué(e)"
msgid "Mark as to do" msgid "Mark as to do"
msgstr "Marquer comme à faire" 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:4
#: stock/templates/stock/update_after_shopping.jinja:8 #: stock/templates/stock/update_after_shopping.jinja:8
#, python-format
msgid "Update %(s)s's quantity after shopping" msgid "Update %(s)s's quantity after shopping"
msgstr "Mise à jour des stocks selon les quantités achetées pour %(s)s" 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" msgid "You must either choose an existing user or create a new one properly"
msgstr "" msgstr ""
"Vous devez soit choisir un utilisateur existant, ou en créer un proprement." "Vous devez soit choisir un utilisateur existant, ou en créer un proprement."
#~ msgid "Stock items list"
#~ msgstr "Liste des éléments du stock"

View File

@ -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 %}
<h3>{% trans s = stock %}Take items form {{ s }}{% endtrans %}</h3>
<div>
<form method="post" action="" class="inline" style="display:inline">
{% csrf_token %}
{{ form.as_p() }}
<p><input type="submit" value="{% trans %}Take items{% endtrans %}" /></p>
</form>
</div>
{% endblock %}

View File

@ -12,6 +12,7 @@ urlpatterns = [
url(r'^(?P<stock_id>[0-9]+)$', StockItemList.as_view(), name='items_list'), url(r'^(?P<stock_id>[0-9]+)$', StockItemList.as_view(), name='items_list'),
url(r'^(?P<stock_id>[0-9]+)/stockItem/newItem$', StockItemCreateView.as_view(), name='new_item'), url(r'^(?P<stock_id>[0-9]+)/stockItem/newItem$', StockItemCreateView.as_view(), name='new_item'),
url(r'^stockItem/(?P<item_id>[0-9]+)/edit$', StockItemEditView.as_view(), name='edit_item'), url(r'^stockItem/(?P<item_id>[0-9]+)/edit$', StockItemEditView.as_view(), name='edit_item'),
url(r'^(?P<stock_id>[0-9]+)/stockItem/takeItems$', StockTakeItemsBaseFormView.as_view(), name='take_items'),
# ShoppingList urls # ShoppingList urls
url(r'^(?P<stock_id>[0-9]+)/shoppingList/list$', StockShoppingListView.as_view(), name='shoppinglist_list'), url(r'^(?P<stock_id>[0-9]+)/shoppingList/list$', StockShoppingListView.as_view(), name='shoppinglist_list'),

View File

@ -8,10 +8,9 @@ from django.forms.models import modelform_factory
from django.core.urlresolvers import reverse_lazy, reverse from django.core.urlresolvers import reverse_lazy, reverse
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin, TabedViewMixin from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin, TabedViewMixin
from counter.views import CounterAdminTabsMixin from counter.views import CounterAdminTabsMixin, CounterTabsMixin
from counter.models import Counter from counter.models import Counter, ProductType
from stock.models import Stock, StockItem from stock.models import Stock, StockItem, ShoppingList
class StockItemList(CounterAdminTabsMixin, CanCreateMixin, ListView): class StockItemList(CounterAdminTabsMixin, CanCreateMixin, ListView):
@ -23,6 +22,9 @@ class StockItemList(CounterAdminTabsMixin, CanCreateMixin, ListView):
pk_url_kwarg = "stock_id" pk_url_kwarg = "stock_id"
current_tab = "stocks" 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): class StockListView(CounterAdminTabsMixin, CanViewMixin, ListView):
""" """
A list view for the admins A list view for the admins
@ -357,3 +359,77 @@ class StockUpdateAfterShopppingBaseFormView(CounterAdminTabsMixin, CanEditMixin,
def get_success_url(self): def get_success_url(self):
self.kwargs.pop('shoppinglist_id', None) self.kwargs.pop('shoppinglist_id', None)
return reverse_lazy('stock:shoppinglist_list', args=self.args, kwargs=self.kwargs) 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)