Commit 539facca authored by Lo-J's avatar Lo-J

Update shopping list history (ShoppingListItem creation)

parent 62200827
Pipeline #689 passed with stage
in 3 minutes and 23 seconds
from django.contrib import admin
from stock.models import Stock, StockItem
from stock.models import Stock, StockItem, ShoppingList, ShoppingListItem
# Register your models here.
admin.site.register(Stock)
admin.site.register(StockItem)
\ No newline at end of file
admin.site.register(StockItem)
admin.site.register(ShoppingList)
admin.site.register(ShoppingListItem)
\ No newline at end of file
......@@ -2,6 +2,7 @@
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
......@@ -11,22 +12,42 @@ class Migration(migrations.Migration):
]
operations = [
migrations.CreateModel(
name='ShoppingList',
fields=[
('id', models.AutoField(primary_key=True, auto_created=True, serialize=False, verbose_name='ID')),
('date', models.DateTimeField(verbose_name='date')),
('name', models.CharField(max_length=64, verbose_name='name')),
('todo', models.BooleanField(verbose_name='todo')),
],
),
migrations.CreateModel(
name='Stock',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('id', models.AutoField(primary_key=True, auto_created=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=64, verbose_name='name')),
('counter', models.OneToOneField(to='counter.Counter', related_name='stock', verbose_name='counter')),
('counter', models.OneToOneField(to='counter.Counter', verbose_name='counter', related_name='stock')),
],
),
migrations.CreateModel(
name='StockItem',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('id', models.AutoField(primary_key=True, auto_created=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=64, verbose_name='name')),
('unit_quantity', models.IntegerField(default=0, verbose_name='unit quantity')),
('effective_quantity', models.IntegerField(default=0, verbose_name='effective quantity')),
('stock_owner', models.ForeignKey(related_name='stock_owner', to='stock.Stock')),
('unit_quantity', models.IntegerField(default=0, help_text='number of element in one box', verbose_name='unit quantity')),
('effective_quantity', models.IntegerField(default=0, help_text='number of box', verbose_name='effective quantity')),
('stock_owner', models.ForeignKey(to='stock.Stock', related_name='items')),
('type', models.ForeignKey(to='counter.ProductType', on_delete=django.db.models.deletion.SET_NULL, null=True, verbose_name='type', blank=True, related_name='stock_items')),
],
),
migrations.AddField(
model_name='shoppinglist',
name='items_to_buy',
field=models.ManyToManyField(to='stock.StockItem', related_name='shopping_lists', verbose_name='items to buy'),
),
migrations.AddField(
model_name='shoppinglist',
name='stock_owner',
field=models.ForeignKey(to='stock.Stock', null=True, related_name='shopping_lists'),
),
]
......@@ -2,30 +2,28 @@
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('counter', '0011_auto_20161004_2039'),
('stock', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='stockitem',
name='type',
field=models.ForeignKey(to='counter.ProductType', blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, verbose_name='type', related_name='stockItem_type'),
name='bought_quantity',
field=models.IntegerField(help_text='quantity bought during the last shopping session', default=6, verbose_name='quantity bought'),
),
migrations.AlterField(
migrations.AddField(
model_name='stockitem',
name='effective_quantity',
field=models.IntegerField(help_text='total number of bottle/barrel', verbose_name='effective quantity', default=0),
name='minimal_quantity',
field=models.IntegerField(help_text='if the effective quantity is less than the minimal, item is added to the shopping list', default=1, verbose_name='minimal quantity'),
),
migrations.AlterField(
migrations.AddField(
model_name='stockitem',
name='unit_quantity',
field=models.IntegerField(help_text='number of beer in one crate (equal one for barrels)', verbose_name='unit quantity', default=0),
name='tobuy_quantity',
field=models.IntegerField(help_text='quantity to buy during the next shopping session', default=6, verbose_name='quantity to buy'),
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('stock', '0002_auto_20161113_2325'),
]
operations = [
migrations.AlterField(
model_name='stockitem',
name='effective_quantity',
field=models.IntegerField(default=0, verbose_name='effective quantity', help_text='number of box'),
),
migrations.AlterField(
model_name='stockitem',
name='stock_owner',
field=models.ForeignKey(related_name='items', to='stock.Stock'),
),
migrations.AlterField(
model_name='stockitem',
name='type',
field=models.ForeignKey(related_name='stock_items', verbose_name='type', null=True, to='counter.ProductType', blank=True, on_delete=django.db.models.deletion.SET_NULL),
),
migrations.AlterField(
model_name='stockitem',
name='unit_quantity',
field=models.IntegerField(default=0, verbose_name='unit quantity', help_text='number of element in one box'),
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stock', '0002_auto_20170105_2017'),
]
operations = [
migrations.RemoveField(
model_name='stockitem',
name='bought_quantity',
),
migrations.RemoveField(
model_name='stockitem',
name='tobuy_quantity',
),
migrations.AddField(
model_name='shoppinglist',
name='bought_quantity',
field=models.IntegerField(help_text='quantity bought during the last shopping session', default=6, verbose_name='quantity bought'),
),
migrations.AddField(
model_name='shoppinglist',
name='tobuy_quantity',
field=models.IntegerField(help_text='quantity to buy during the next shopping session', default=6, verbose_name='quantity to buy'),
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stock', '0003_auto_20170105_2138'),
]
operations = [
migrations.RemoveField(
model_name='shoppinglist',
name='bought_quantity',
),
migrations.RemoveField(
model_name='shoppinglist',
name='tobuy_quantity',
),
migrations.AddField(
model_name='stockitem',
name='bought_quantity',
field=models.IntegerField(help_text='quantity bought during the last shopping session', verbose_name='quantity bought', default=6),
),
migrations.AddField(
model_name='stockitem',
name='tobuy_quantity',
field=models.IntegerField(help_text='quantity to buy during the next shopping session', verbose_name='quantity to buy', default=6),
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stock', '0004_auto_20170105_2145'),
]
operations = [
migrations.CreateModel(
name='ShoppingListItems',
fields=[
('id', models.AutoField(primary_key=True, auto_created=True, verbose_name='ID', serialize=False)),
('name', models.CharField(max_length=64, verbose_name='name')),
('tobuy_quantity', models.IntegerField(verbose_name='quantity to buy', default=6, help_text='quantity to buy during the next shopping session')),
('bought_quantity', models.IntegerField(verbose_name='quantity bought', default=6, help_text='quantity bought during the last shopping session')),
],
),
migrations.RemoveField(
model_name='stockitem',
name='bought_quantity',
),
migrations.RemoveField(
model_name='stockitem',
name='tobuy_quantity',
),
migrations.AddField(
model_name='shoppinglist',
name='comment',
field=models.TextField(null=True, verbose_name='comment', blank=True),
),
migrations.AddField(
model_name='shoppinglistitems',
name='shoppinglist_owner',
field=models.ForeignKey(related_name='item_quantity', to='stock.ShoppingList'),
),
migrations.AddField(
model_name='shoppinglistitems',
name='stockitem_owner',
field=models.ForeignKey(related_name='item', null=True, to='stock.StockItem'),
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stock', '0005_auto_20170107_0857'),
]
operations = [
migrations.CreateModel(
name='ShoppingListItem',
fields=[
('id', models.AutoField(serialize=False, auto_created=True, primary_key=True, verbose_name='ID')),
('name', models.CharField(max_length=64, verbose_name='name')),
('tobuy_quantity', models.IntegerField(default=6, help_text='quantity to buy during the next shopping session', verbose_name='quantity to buy')),
('bought_quantity', models.IntegerField(default=0, help_text='quantity bought during the last shopping session', verbose_name='quantity bought')),
],
),
migrations.RemoveField(
model_name='shoppinglistitems',
name='shoppinglist_owner',
),
migrations.RemoveField(
model_name='shoppinglistitems',
name='stockitem_owner',
),
migrations.RemoveField(
model_name='shoppinglist',
name='items_to_buy',
),
migrations.DeleteModel(
name='ShoppingListItems',
),
migrations.AddField(
model_name='shoppinglistitem',
name='shopping_lists',
field=models.ManyToManyField(related_name='shopping_items_to_buy', to='stock.ShoppingList', verbose_name='shopping lists'),
),
migrations.AddField(
model_name='shoppinglistitem',
name='stockitem_owner',
field=models.ForeignKey(related_name='item', null=True, to='stock.StockItem'),
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('counter', '0011_auto_20161004_2039'),
('stock', '0006_auto_20170107_0910'),
]
operations = [
migrations.AddField(
model_name='shoppinglistitem',
name='type',
field=models.ForeignKey(null=True, verbose_name='type', on_delete=django.db.models.deletion.SET_NULL, to='counter.ProductType', blank=True, related_name='shoppinglist_items'),
),
]
......@@ -7,13 +7,13 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stock', '0013_auto_20161228_1006'),
('stock', '0007_shoppinglistitem_type'),
]
operations = [
migrations.AlterField(
model_name='shoppinglist',
name='stock_owner',
field=models.ForeignKey(related_name='shopping_lists', null=True, to='stock.Stock'),
model_name='shoppinglistitem',
name='stockitem_owner',
field=models.ForeignKey(related_name='shopping_item', to='stock.StockItem', null=True),
),
]
......@@ -29,6 +29,8 @@ class StockItem(models.Model):
name = models.CharField(_('name'), max_length=64)
unit_quantity = models.IntegerField(_('unit quantity'), default=0, help_text='number of element in one box')
effective_quantity = models.IntegerField(_('effective quantity'), default=0, help_text='number of box')
minimal_quantity = models.IntegerField(_('minimal quantity'), default=1,
help_text='if the effective quantity is less than the minimal, item is added to the shopping list')
type = models.ForeignKey(ProductType, related_name="stock_items", verbose_name=_("type"), null=True, blank=True,
on_delete=models.SET_NULL)
stock_owner = models.ForeignKey(Stock, related_name="items")
......@@ -49,14 +51,36 @@ class ShoppingList(models.Model):
date = models.DateTimeField(_('date'))
name = models.CharField(_('name'), max_length=64)
todo = models.BooleanField(_('todo'))
items_to_buy = models.ManyToManyField(StockItem, verbose_name=_('items to buy'), related_name="shopping_lists")
comment = models.TextField(_('comment'), null=True, blank=True)
stock_owner = models.ForeignKey(Stock, null=True, related_name="shopping_lists")
def __str__(self):
return "%s (%s)" % (self.name, self.effective_quantity)
return "%s (%s)" % (self.name, self.date)
def get_absolute_url(self):
return reverse('stock:shoppinglist_list')
def can_be_viewed_by(self, user):
return user.is_in_group(settings.SITH_GROUP_COUNTER_ADMIN_ID)
class ShoppingListItem(models.Model):
"""
"""
shopping_lists = models.ManyToManyField(ShoppingList, verbose_name=_('shopping lists'), related_name="shopping_items_to_buy")
stockitem_owner = models.ForeignKey(StockItem, related_name="shopping_item", null=True)
name = models.CharField(_('name'), max_length=64)
type = models.ForeignKey(ProductType, related_name="shoppinglist_items", verbose_name=_("type"), null=True, blank=True,
on_delete=models.SET_NULL)
tobuy_quantity = models.IntegerField(_('quantity to buy'), default=6, help_text="quantity to buy during the next shopping session")
bought_quantity = models.IntegerField(_('quantity bought'), default=0, help_text="quantity bought during the last shopping session")
def __str__(self):
return "%s - %s" % (self.name, self.shopping_lists.first())
def can_be_viewed_by(self, user):
return user.is_in_group(settings.SITH_GROUP_COUNTER_ADMIN_ID)
def get_absolute_url(self):
return reverse('stock:shoppinglist_list')
......@@ -10,25 +10,42 @@
{% endif %}
<h3>{{ shoppinglist.name }}</h3>
{% for t in ProductType.objects.order_by('name') %}
{% if shoppinglist.items_to_buy.filter(type=t) %}
{% for t in ProductType.objects.order_by('name').all() %}
{% if shoppinglist.shopping_items_to_buy.filter(type=t) %}
<h4>{{ t }}</h4>
<br>
<table>
<thead>
<tr>
<td>{% trans %}Name{% endtrans %}</td>
<td>{% trans %}Number{% endtrans %}</td>
<td>{% trans %}Quantity asked{% endtrans %}</td>
<td>{% trans %}Quantity bought{% endtrans %}</td>
</tr>
</thead>
<tbody>
{% for i in shoppinglist.items_to_buy.filter(type=t).order_by('name') %}
{% for i in shoppinglist.shopping_items_to_buy.filter(type=t).order_by('name').all() %}
<tr>
<td>{{ i.name }}</td>
<td>{{ i.tobuy_quantity }}</td>
<td>{{ i.bought_quantity }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% endfor %}
<h4>Other</h4>
<br>
<table>
<thead>
<tr>
<td>{% trans %}Comments{% endtrans %}</td>
</tr>
</thead>
<tbody>
<tr>
<td>{{ shoppinglist.comment }}</td>
</tr>
</tbody>
</table>
{% endblock %}
\ No newline at end of file
......@@ -28,11 +28,11 @@ Shopping list for {{ stock }}
</tr>
</thead>
<tbody>
{% for s in shoppinglist_list.filter(todo=True).filter(stock_owner=stock).order_by('-date') %}
{% for s in stock.shopping_lists.filter(todo=True).filter(stock_owner=stock).order_by('-date').all() %}
<tr>
<td>{{ s.date|localtime|date("Y-m-d H:i") }}</td>
<td><a href="{{ url('stock:shoppinglist_items', stock_id=stock.id, shoppinglist_id=s.id)}}">{{ s.name }}</a></td>
<td>{{ s.items_to_buy.count() }}</td>
<td>{{ s.shopping_items_to_buy.count() }}</td>
<td>
<a href="{{ url('stock:update_after_shopping', stock_id=stock.id, shoppinglist_id=s.id)}}">{% trans %}Update stock{% endtrans %}</a>
</td>
......@@ -57,11 +57,11 @@ Shopping list for {{ stock }}
</tr>
</thead>
<tbody>
{% for s in shoppinglist_list.filter(todo=False).filter(stock_owner=stock).order_by('-date') %}
{% for s in stock.shopping_lists.filter(todo=False).filter(stock_owner=stock).order_by('-date').all() %}
<tr>
<td>{{ s.date|localtime|date("Y-m-d H:i") }}</td>
<td><a href="{{ url('stock:shoppinglist_items', stock_id=stock.id, shoppinglist_id=s.id)}}">{{ s.name }}</a></td>
<td>{{ s.items_to_buy.count() }}</td>
<td>{{ s.shopping_items_to_buy.count() }}</td>
<td>
<a href="{{ url('stock:shoppinglist_set_todo', stock_id=stock.id, shoppinglist_id=s.id)}}">{% trans %}Mark as to do{% endtrans %}</a>
</td>
......
from collections import OrderedDict
from datetime import datetime, timedelta
from django.utils import timezone
from django.shortcuts import render, get_object_or_404
from django.views.generic import ListView, DetailView, RedirectView, TemplateView
from django.views.generic.edit import UpdateView, CreateView, DeleteView, ProcessFormView, FormMixin
from django.views.generic.edit import UpdateView, CreateView, DeleteView, ProcessFormView, FormMixin, BaseFormView
from django.utils.translation import ugettext_lazy as _
from django import forms
from django.http import HttpResponseRedirect, HttpResponse
from django.forms.models import modelform_factory
from django.core.urlresolvers import reverse_lazy, reverse
from django.db import transaction, DataError
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin, TabedViewMixin
from counter.views import CounterAdminTabsMixin, CounterTabsMixin
from counter.models import Counter, ProductType
from stock.models import Stock, StockItem, ShoppingList
from stock.models import Stock, StockItem, ShoppingList, ShoppingListItem
class StockItemList(CounterAdminTabsMixin, CanCreateMixin, ListView):
......@@ -76,7 +81,7 @@ class StockItemEditView(CounterAdminTabsMixin, CanEditPropMixin, UpdateView):
An edit view for a stock item
"""
model = StockItem
form_class = modelform_factory(StockItem, fields=['name', 'unit_quantity', 'effective_quantity', 'type', 'stock_owner'])
form_class = modelform_factory(StockItem, fields=['name', 'unit_quantity', 'effective_quantity', 'minimal_quantity', 'type', 'stock_owner'])
pk_url_kwarg = "item_id"
template_name = 'core/edit.jinja'
current_tab = "stocks"
......@@ -104,7 +109,7 @@ class StockItemCreateView(CounterAdminTabsMixin, CanCreateMixin, CreateView):
A create view for a new StockItem
"""
model = StockItem
form_class = modelform_factory(StockItem, fields=['name', 'unit_quantity', 'effective_quantity', 'type', 'stock_owner'])
form_class = modelform_factory(StockItem, fields=['name', 'unit_quantity', 'effective_quantity', 'minimal_quantity', 'type', 'stock_owner'])
template_name = 'core/create.jinja'
pk_url_kwarg = "stock_id"
current_tab = "stocks"
......@@ -144,13 +149,21 @@ class StockItemQuantityForm(forms.BaseForm):
shopping_list.stock_owner = self.stock
shopping_list.save()
for k,t in self.cleaned_data.items():
if int(t) > 0 :
item_id = int(k[5:])
item = StockItem.objects.filter(id=item_id).first()
item.tobuy_quantity = t
item.shopping_lists.add(shopping_list)
item.save()
if k == 'name':
shopping_list.name = t
shopping_list.save()
elif k == "comment":
shopping_list.comment = t
shopping_list.save()
else:
if t > 0 :
item_id = int(k[5:])
item = StockItem.objects.filter(id=item_id).first()
shoppinglist_item = ShoppingListItem(stockitem_owner=item, name=item.name, type=item.type, tobuy_quantity=t)
shoppinglist_item.save()
shoppinglist_item.shopping_lists.add(shopping_list)
shoppinglist_item.save()
return self.cleaned_data
class StockItemQuantityBaseFormView(CounterAdminTabsMixin, CanEditMixin, DetailView, BaseFormView):
......@@ -165,13 +178,15 @@ class StockItemQuantityBaseFormView(CounterAdminTabsMixin, CanEditMixin, DetailV
def get_form_class(self):
fields = OrderedDict()
kwargs = {}
fields['name'] = forms.CharField(max_length=30, required=True, label='Shopping list name')
for t in ProductType.objects.order_by('name').all():
for i in self.stock.items.filter(type=t).order_by('name').all():
if i.effective_quantity <= i.minimal_quantity:
field_name = "item-%s" % (str(i.id))
fields[field_name] = forms.CharField(max_length=30, required=True, label=str(i),
fields[field_name] = forms.IntegerField(required=True, label=str(i),
help_text=str(i.effective_quantity)+" left")
kwargs[field_name] = i.effective_quantity
fields['comment'] = forms.CharField(widget=forms.Textarea(), required=False,
initial="Add here, items to buy that are not reference as a product (example : sponge, knife, mugs ...)")
kwargs['stock_id'] = self.stock.id
kwargs['base_fields'] = fields
return type('StockItemQuantityForm', (StockItemQuantityForm,), kwargs)
......@@ -272,11 +287,18 @@ class StockUpdateAfterShopppingForm(forms.BaseForm):
with transaction.atomic():
self.shoppinglist = ShoppingList.objects.filter(id=self.shoppinglist_id).first()
for k,t in self.cleaned_data.items():
item_id = int(k[5:])
shoppinglist_item_id = int(k[5:])
#item_id = int(k[5:])
if int(t) > 0 :
item = StockItem.objects.filter(id=item_id).first()
item.effective_quantity += int(t)
item.save()
shoppinglist_item = ShoppingListItem.objects.filter(id=shoppinglist_item_id).first()
shoppinglist_item.bought_quantity = int(t)
shoppinglist_item.save()
shoppinglist_item.stockitem_owner.effective_quantity += int(t)
shoppinglist_item.stockitem_owner.save()
#item = StockItem.objects.filter(id=item_id).first()
#item.bought_quantity = int(t)
#item.effective_quantity += int(t)
#item.save()
self.shoppinglist.todo = False
self.shoppinglist.save()
return self.cleaned_data
......@@ -294,7 +316,7 @@ class StockUpdateAfterShopppingBaseFormView(CounterAdminTabsMixin, CanEditMixin,
fields = OrderedDict()
kwargs = {}
for t in ProductType.objects.order_by('name').all():
for i in self.shoppinglist.items_to_buy.filter(type=t).order_by('name').all():
for i in self.shoppinglist.shopping_items_to_buy.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),
help_text=str(i.tobuy_quantity) + " asked")
......@@ -341,9 +363,9 @@ class StockTakeItemsForm(forms.BaseForm):
with transaction.atomic():
for k,t in self.cleaned_data.items():
item_id = int(k[5:])
if int(t) > 0 :
if t > 0 :
item = StockItem.objects.filter(id=item_id).first()
item.effective_quantity -= int(t)
item.effective_quantity -= t
item.save()
return self.cleaned_data
......@@ -363,7 +385,7 @@ class StockTakeItemsBaseFormView(CounterTabsMixin, CanEditMixin, DetailView, Bas
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))
fields[field_name] = forms.IntegerField(required=False, label=str(i), help_text="("+ str(i.effective_quantity) + " left)")
kwargs[field_name] = i.effective_quantity
kwargs['stock_id'] = self.stock.id
kwargs['counter_id'] = self.stock.counter.id
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment