Manage variations for items with exactly one property

This commit is contained in:
Raphael Michel
2014-09-29 12:44:06 +02:00
parent d831980f1e
commit 72de56493e
7 changed files with 154 additions and 2 deletions

View File

@@ -538,9 +538,10 @@ class ItemVariation(models.Model):
)
active = models.BooleanField(
default=True,
verbose_name=_("Active"),
)
default_price = models.DecimalField(
decimal_places=2, max_digits=7,
null=True, blank=True,
verbose_name=_("Default price")
verbose_name=_("Default price"),
)

View File

@@ -0,0 +1,16 @@
td > .form-group {
margin-bottom: 0;
}
td > .errorlist {
color: #a94442;
list-style-type: none;
padding: 0;
margin: 0;
}
td > .form-group > .checkbox {
margin-top: 0;
margin-bottom: 0;
}
.has-success .form-control {
border-color: #cccccc;
}

View File

@@ -1,3 +1,4 @@
@import "../../../../tixlbase/static/bootstrap/less/bootstrap.less";
@import "../../../../tixlbase/static/fontawesome/less/font-awesome.less";
@fa-font-path: "../../fontawesome/fonts";
@import "forms.less";

View File

@@ -5,6 +5,7 @@
<h1>{% trans "Modify item:" %} {{ item.name }}</h1>
<ul class="nav nav-pills">
<li {% if "event.item" == url_name %}class="active"{% endif %}><a href="{% url 'control:event.item' organizer=request.event.organizer.slug event=request.event.slug item=item.pk %}">{% trans "General information" %}</a></li>
<li {% if "event.item.variations" == url_name %}class="active"{% endif %}><a href="{% url 'control:event.item.variations' organizer=request.event.organizer.slug event=request.event.slug item=item.pk %}">{% trans "Variations" %}</a></li>
</ul>
{% block inside %}
{% endblock %}

View File

@@ -0,0 +1,36 @@
{% extends "tixlcontrol/item/base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% block inside %}
<h2>{% trans "Variations" %}</h2>
<form action="" method="post">
{% csrf_token %}
<table class="table">
<thead>
<tr>
<th>{{ properties.0 }}</th>
<th>{% trans "Active" %}</th>
<th>{% trans "Price" %}</th>
</tr>
</thead>
<tbody>
{% for form in forms %}
{% bootstrap_form_errors form type='all' layout='inline' %}
<tr>
<td>{{ form.values.0 }}</td>
<td>{% bootstrap_field form.active layout='inline' %}</td>
<td>{% bootstrap_field form.default_price layout='inline' %} {{ form.default_price.errors }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="form-group">
<div class="col-sm-12">
<button type="submit" class="btn btn-primary">
{% trans "Save" %}
</button>
</div>
</div>
</form>
{% endblock %}

View File

@@ -21,6 +21,7 @@ urlpatterns += patterns(
url(r'^settings$', event.EventUpdate.as_view(), name='event.settings'),
url(r'^items$', item.ItemList.as_view(), name='event.items'),
url(r'^items/(?P<item>\d+)/$', item.ItemUpdateGeneral.as_view(), name='event.item'),
url(r'^items/(?P<item>\d+)/variations$', item.ItemVariations.as_view(), name='event.item.variations'),
url(r'^categories$', item.CategoryList.as_view(), name='event.items.categories'),
url(r'^properties$', item.PropertyList.as_view(), name='event.items.properties'),
)

View File

@@ -1,9 +1,11 @@
from django.views.generic import ListView
from django.views.generic.edit import UpdateView
from django.views.generic.base import TemplateView
from django.views.generic.detail import SingleObjectMixin
from django.core.urlresolvers import resolve, reverse
from django import forms
from tixlbase.models import Item, ItemCategory, Property
from tixlbase.models import Item, ItemCategory, Property, ItemVariation
from tixlcontrol.permissions import EventPermissionRequiredMixin
@@ -81,3 +83,97 @@ class ItemUpdateGeneral(EventPermissionRequiredMixin, UpdateView):
'event': self.request.event.slug,
'item': self.get_object().pk,
}) + '?success=true'
class ItemVariationForm(forms.ModelForm):
class Meta:
model = ItemVariation
localized_fields = '__all__'
fields = [
'active',
'default_price',
]
class ItemVariations(TemplateView, SingleObjectMixin):
model = Item
context_object_name = 'item'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.item = None
def get_forms(self):
"""
Returns one form per possible item variation. The forms are returned
twice: The first entry in the returned tuple contains a 1-, 2- or
3-dimensional list, depending on the number of properties associated
with this item (this is being used for form display), the second
contains all forms in one single list (this is used for processing).
"""
forms = []
forms_flat = []
variations = self.object.get_all_variations()
data = self.request.POST if self.request.method == 'POST' else None
if self.dimension == 1:
for var in variations:
val = [i[1] for i in sorted([it for it in var.items() if it[0] != 'variation'])]
if 'variation' in var:
form = ItemVariationForm(
data,
instance=var['variation'],
prefix=",".join([str(i) for i in val])
)
else:
form = ItemVariationForm(
data,
instance=ItemVariation(item=self.object),
prefix=",".join([str(i) for i in val])
)
form.values = val
forms.append(form)
forms_flat = forms
return forms, forms_flat
def main(self, request, *args, **kwargs):
self.object = self.get_object()
self.properties = self.object.properties.all()
self.dimension = self.properties.count()
self.forms, self.forms_flat = self.get_forms()
def get(self, request, *args, **kwargs):
self.main(request, *args, **kwargs)
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
def post(self, request, *args, **kwargs):
self.main(request, *args, **kwargs)
context = self.get_context_data(object=self.object)
for form in self.forms_flat:
if form.is_valid():
if form.instance.pk is None:
form.save()
form.instance.values.add(*form.values)
else:
form.save()
return self.render_to_response(context)
def get_object(self, queryset=None):
if not self.item:
url = resolve(self.request.path_info)
self.item = self.request.event.items.get(
id=url.kwargs['item']
)
return self.item
def get_template_names(self):
if self.dimension == 1:
return ['tixlcontrol/item/variations_1d.html']
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['forms'] = self.forms
context['properties'] = self.properties
return context