diff --git a/batiskaf/templates/jinja2/base.jinja b/batiskaf/templates/jinja2/base.jinja index 41ea593..40e5226 100644 --- a/batiskaf/templates/jinja2/base.jinja +++ b/batiskaf/templates/jinja2/base.jinja @@ -164,6 +164,9 @@ {% endfor %} +
  • Распродажа + +
  • diff --git a/batiskaf/templates/jinja2/category.jinja b/batiskaf/templates/jinja2/category.jinja index 457b93e..d66ee67 100644 --- a/batiskaf/templates/jinja2/category.jinja +++ b/batiskaf/templates/jinja2/category.jinja @@ -2,6 +2,8 @@ {% block title %} {% if category %} {{ category.title }}{% for parent in category.get_parents() %} > {{ parent.title }}{% endfor %} + {% elif 'sale' in request.path %} + Скидки {% else %} Поиск по запросу {{ request.GET['q'] }} {% endif %} @@ -15,6 +17,8 @@
  • {{ parent.title }}
  • {% endfor %}
  • {{ category.title }}
  • + {% elif 'sale' in request.path %} +
  • Скидки
  • {% else %}
  • Поиск по запросу {{ request.GET['q'] }}
  • {% endif %} @@ -94,8 +98,15 @@
    + {% if is_sale %} +
    + -{{ product.min_price_variation().discount }}% +
    + {% endif %} {% set im = product.main_image()|thumbnail("420x420") %} - + + Купить {{ product.title }}
    @@ -105,7 +116,11 @@
    +{% if is_sale %} + {{ product.min_price_variation().price }} ₸ + {% endif %} {{ product.min_price() }} ₸ +
    {% if product.in_stock() %} diff --git a/static/less/_.css b/static/less/_.css index f41a87a..5f8c86d 100644 --- a/static/less/_.css +++ b/static/less/_.css @@ -955,3 +955,13 @@ ul.messages { margin: 40px auto; position: relative; } +.sale-percent-block { + background: #E9573F; + width: 50px; + height: 50px; + text-align: center; + color: white; + top: 0; + font-size: 20px; + line-height: 50px; +} diff --git a/static/less/_.less b/static/less/_.less index 6a37b3c..72857ff 100644 --- a/static/less/_.less +++ b/static/less/_.less @@ -828,3 +828,13 @@ ul.messages { position: relative } +.sale-percent-block{ + background: #E9573F; + width: 50px; + height: 50px; + text-align: center; + color: white; + top: 0; + font-size: 20px; + line-height: 50px; +} \ No newline at end of file diff --git a/store/admin.py b/store/admin.py index 588c3d6..0b5f769 100644 --- a/store/admin.py +++ b/store/admin.py @@ -61,7 +61,7 @@ class ImageInProductInline(admin.TabularInline): class ProductVariationInline(admin.TabularInline): model = ProductVariation - fields = ['variation', 'article', 'price', 'weight', 'in_stock'] + fields = ['variation', 'article', 'price', 'weight', 'in_stock', 'discount'] extra = 1 diff --git a/store/migrations/0022_productvariation_discount.py b/store/migrations/0022_productvariation_discount.py new file mode 100644 index 0000000..6914695 --- /dev/null +++ b/store/migrations/0022_productvariation_discount.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('store', '0021_orderdata_status'), + ] + + operations = [ + migrations.AddField( + model_name='productvariation', + name='discount', + field=models.IntegerField(default=0, verbose_name='Скидка %'), + ), + ] diff --git a/store/models.py b/store/models.py index d88153e..4cc6659 100644 --- a/store/models.py +++ b/store/models.py @@ -178,16 +178,33 @@ class Product(models.Model): def in_stock(self): return self.variations.filter(in_stock__gt=0).count() + def min_price_variation(self): + min_v = None + for v in self.variations.all(): + if not min_v: + min_v = v + else: + if v.get_price() < min_v.get_price(): + min_v = v + return min_v + def min_price(self): - retval = self.variations.filter(in_stock__gt=0).aggregate( - Min('price'))['price__min'] or 0 - if not retval: - retval = self.variations.aggregate(Min('price'))['price__min'] or 0 + return self.min_price_variation().get_price() + + def is_discount(self): + return self.variations.filter(discount__gt=0).count() > 0 + - if retval > 10000: - return int(retval * Decimal('.95')) - else: - return int(retval * Decimal('.93')) + + # retval = self.variations.filter(in_stock__gt=0).aggregate( + # Min('price'))['price__min'] or 0 + # if not retval: + # retval = self.variations.aggregate(Min('price'))['price__min'] or 0 + # + # if retval > 10000: + # return int(retval * Decimal('.95')) + # else: + # return int(retval * Decimal('.93')) def get_absolute_url(self): retval = '/store/' @@ -197,7 +214,6 @@ class Product(models.Model): retval += main_category.slug + '/product-' + self.slug return retval - class ProductVariation(models.Model): product = models.ForeignKey( Product, verbose_name='Товар', related_name='variations') @@ -209,7 +225,7 @@ class ProductVariation(models.Model): article = models.CharField( 'Артикул', max_length=32, null=True, blank=True, default='') weight = models.FloatField('Вес (кг)', default=0.1, null=False, blank=False) - # weight = models.FloatField('Вес (кг)', default=0.1, null=False, blank=False) + discount = models.IntegerField('Скидка %', default=0, blank=False, null=False) class Meta: verbose_name = 'разновидность товара' @@ -219,11 +235,13 @@ class ProductVariation(models.Model): return self.variation def get_price(self): - if self.price > 10000: - return int(self.price * Decimal('.95')) + if self.discount: + return int(self.price - (self.price/100*self.discount)) else: - return int(self.price * Decimal('.93')) - + if self.price > 10000: + return int(self.price * Decimal('.95')) + else: + return int(self.price * Decimal('.93')) class AttributesInProduct(models.Model): attribute = models.ForeignKey( diff --git a/store/urls.py b/store/urls.py index e9c39bd..e73287f 100644 --- a/store/urls.py +++ b/store/urls.py @@ -11,6 +11,9 @@ urlpatterns = patterns('', url(r'^search/$', CategoryView.as_view(is_search=True), name='store_search'), + url(r'^sale/$', CategoryView.as_view(is_sale=True), + name='store_sale'), + url(r'^cart/add/$', CartAddView.as_view( permanent=False), name='store_cart_add'), url(r'^cart/remove/$', CartRemoveView.as_view( diff --git a/store/views.py b/store/views.py index e768600..af688e1 100644 --- a/store/views.py +++ b/store/views.py @@ -33,6 +33,7 @@ class CategoryView(CategoryBaseView, TemplateView): products_qs = None sort = None is_search = False + is_sale = False ORDER_PARAMETERS = ( ('date', 'pk'), @@ -92,13 +93,16 @@ class CategoryView(CategoryBaseView, TemplateView): def get_context_data(self, **kwargs): retval = super(CategoryView, self).get_context_data() q = None - if not self.is_search: - self.category = self._get_full_category(kwargs['categories']) - self.products_qs = self.category.get_all_products().order_by('-pk') - else: + if self.is_search: q = self.request.GET.get('q', '') self.products_qs = Product.objects.filter(title__icontains=q).order_by('-pk') retval['brands'] = list(set(map(lambda item: item.brand, self.products_qs))) + if self.is_sale: + self.products_qs = Product.objects.filter(variations__discount__gt=0).distinct().order_by('-pk') + retval['brands'] = list(set(map(lambda item: item.brand, self.products_qs))) + else: + self.category = self._get_full_category(kwargs['categories']) + self.products_qs = self.category.get_all_products().order_by('-pk') self.brand_pks = self._get_brand_pks() self.sort = self._get_sort() @@ -127,6 +131,7 @@ class CategoryView(CategoryBaseView, TemplateView): retval['category'] = self.category retval['products'] = self.products_qs retval['q'] = q + retval['is_sale'] = self.is_sale return retval