Compare commits
31 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
78e522b1fa | 8 years ago |
|
|
16608ac882 | 8 years ago |
|
|
1b00dd3df7 | 8 years ago |
|
|
aece04aa6c | 8 years ago |
|
|
a0f1e499af | 8 years ago |
|
|
a690891eaf | 8 years ago |
|
|
9a9cbea429 | 8 years ago |
|
|
ed9bd43fb0 | 8 years ago |
|
|
b283f5f758 | 8 years ago |
|
|
4e188bbfbf | 8 years ago |
|
|
29a55180e3 | 8 years ago |
|
|
c95c522754 | 8 years ago |
|
|
4ad070c9bc | 8 years ago |
|
|
a8957c9d10 | 8 years ago |
|
|
5a56c404a4 | 8 years ago |
|
|
1603c2bd50 | 8 years ago |
|
|
4aa8633aae | 8 years ago |
|
|
0d8a608da0 | 8 years ago |
|
|
d5e72786fe | 8 years ago |
|
|
7d372f1ad3 | 8 years ago |
|
|
99c2a596c0 | 8 years ago |
|
|
f40786a535 | 8 years ago |
|
|
58d082e8d5 | 8 years ago |
|
|
2ada05ea76 | 8 years ago |
|
|
ab8a623b74 | 8 years ago |
|
|
b6a6fc47ea | 8 years ago |
|
|
0b37076dfd | 8 years ago |
|
|
47019cf459 | 8 years ago |
|
|
3f352e2cc8 | 8 years ago |
|
|
a976fe8405 | 8 years ago |
|
|
ec5e86ce3f | 8 years ago |
47 changed files with 1160 additions and 81 deletions
@ -0,0 +1,7 @@ |
||||
from __future__ import absolute_import, unicode_literals |
||||
|
||||
# This will make sure the app is always imported when |
||||
# Django starts so that shared_task will use this app. |
||||
from .celery import app as celery_app |
||||
|
||||
__all__ = ['celery_app'] |
||||
@ -0,0 +1,15 @@ |
||||
|
||||
from django.conf import settings |
||||
|
||||
|
||||
def dev(request): |
||||
try: |
||||
PROD_MODE = settings.PROD_MODE |
||||
except AttributeError: |
||||
PROD_MODE = True |
||||
|
||||
context = { |
||||
'PROD_MODE': PROD_MODE |
||||
} |
||||
context['request'] = request |
||||
return context |
||||
@ -1,7 +1,11 @@ |
||||
from easy_thumbnails.files import get_thumbnailer |
||||
from easy_thumbnails.exceptions import InvalidImageFormatError |
||||
|
||||
|
||||
def thumbnail(img, size='420x420'): |
||||
weight, height = size.split('x') |
||||
options = {'size': (int(weight), int(height)), 'background': '#fff'} |
||||
return get_thumbnailer(img).get_thumbnail(options) |
||||
try: |
||||
return get_thumbnailer(img).get_thumbnail(options) |
||||
except (ValueError, InvalidImageFormatError): |
||||
return {'url': ''} |
||||
|
||||
@ -0,0 +1,29 @@ |
||||
{% extends 'base.jinja' %} |
||||
|
||||
{% block meta_description %}{% endblock %} |
||||
|
||||
{% block title %} |
||||
Поймай свою цену |
||||
{% endblock %} |
||||
|
||||
{% block stylesheet %}{% endblock stylesheet %} |
||||
|
||||
|
||||
{% block jss %} |
||||
<script src="/static/js/dtys.js"></script> |
||||
{% endblock jss %} |
||||
|
||||
|
||||
{% block content %} |
||||
<div class="index-goods"> |
||||
<div class="row"> |
||||
<h1>Поймай свою цену</h1> |
||||
|
||||
<div class="dtys"> |
||||
{% for object in object_list %} |
||||
{% include "includes/dtys_product_thumb.jinja" with context %} |
||||
{% endfor %} |
||||
</div> |
||||
</div> |
||||
</div> |
||||
{% endblock content %} |
||||
@ -0,0 +1,50 @@ |
||||
<div class="col-md-4 col-xs-4 col-sm-4 col-lg-4"> |
||||
<div class="thumbnail dtys__product {% if object.is_stopped %}stopped{% endif %}" id="dtys_product_{{ object.id }}"> |
||||
<div class="wait-block"> |
||||
<span class="wait-icon glyphicon glyphicon-refresh glyphicon-refresh-animate"></span> |
||||
</div> |
||||
|
||||
<div class="sold-block alert-danger"> |
||||
<div class="sold-block__message">Продано!</div> |
||||
</div> |
||||
|
||||
{% set product = object.product.product %} |
||||
{% set im = product.main_image()|thumbnail("420x420") %} |
||||
|
||||
<a> |
||||
<img src="/static/{{ im.url|watermark('medium-photo') }}" |
||||
class="img-responsive" alt="Купить {{ product.title }}" |
||||
title="Купить {{ product.title }}" width="210" height="210"> |
||||
</a> |
||||
|
||||
<div class="caption"> |
||||
<div class="title"> |
||||
<span> |
||||
{{ product.title }} |
||||
</span> |
||||
</div> |
||||
|
||||
<div class="price counter"> |
||||
{% if not object.is_stopped %} |
||||
{{ object.current_price_format() }} |
||||
{% else %} |
||||
{{ object.price_stopped }} |
||||
{% endif %} |
||||
</div> |
||||
|
||||
<div class="in-cart"> |
||||
<a class="btn btn-warning btn-block add-to-cart" |
||||
href="/dtys/buy/{{ object.id }}/" |
||||
{% if object.is_stopped %}style="display: none"{% endif %}> |
||||
<span><i class="glyphicon glyphicon-shopping-cart" |
||||
aria-hidden="true"></i> Добавить в корзину</span> |
||||
</a> |
||||
|
||||
<span class="btn btn-warning btn-block fake-add-to-cart" {% if not object.is_stopped %}style="display: none"{% endif %}> |
||||
<span><i class="glyphicon glyphicon-shopping-cart" |
||||
aria-hidden="true"></i> Добавить в корзину</span> |
||||
</span> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
@ -0,0 +1,10 @@ |
||||
DTYS |
||||
|
||||
Для возврата незаказанного товара нужно чтобы работал celery |
||||
Его нужно запустить со следующими параметрами: |
||||
|
||||
celery -A dtys.tasks worker --loglevel=info |
||||
|
||||
|
||||
Выбранный (остановленный) товар возвращается на страницу после некоторого |
||||
количества секунд, указанного в settings.RESUME_DTYS_DELAY_SECONDS |
||||
@ -0,0 +1 @@ |
||||
default_app_config = 'dtys.apps.DtysConfig' |
||||
@ -0,0 +1,14 @@ |
||||
from django.contrib import admin |
||||
|
||||
from .models import DTYSModel |
||||
|
||||
|
||||
@admin.register(DTYSModel) |
||||
class DTYSModelAdmin(admin.ModelAdmin): |
||||
raw_id_fields = ('product',) |
||||
list_display = ( |
||||
'id', |
||||
'product', |
||||
'is_stopped', |
||||
'is_public' |
||||
) |
||||
@ -0,0 +1,8 @@ |
||||
from django.apps import AppConfig |
||||
|
||||
|
||||
class DtysConfig(AppConfig): |
||||
"""Drop `Til You Shop""" |
||||
|
||||
name = 'dtys' |
||||
verbose_name = "Поймай свою цену" |
||||
@ -0,0 +1,34 @@ |
||||
# -*- coding: utf-8 -*- |
||||
# Generated by Django 1.9.3 on 2017-10-26 22:45 |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import migrations, models |
||||
import django.db.models.deletion |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
initial = True |
||||
|
||||
dependencies = [ |
||||
('store', '0061_auto_20170603_0220'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.CreateModel( |
||||
name='DTYSModel', |
||||
fields=[ |
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
('price_start', models.IntegerField()), |
||||
('price_end', models.IntegerField()), |
||||
('price_stopped', models.IntegerField(blank=True, null=True)), |
||||
('start_date', models.DateField()), |
||||
('start_time', models.TimeField()), |
||||
('end_date', models.DateField()), |
||||
('end_time', models.TimeField()), |
||||
('is_stopped', models.BooleanField(default=False)), |
||||
('is_public', models.BooleanField(default=False)), |
||||
('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='store.ProductVariation')), |
||||
], |
||||
), |
||||
] |
||||
@ -0,0 +1,65 @@ |
||||
# -*- coding: utf-8 -*- |
||||
# Generated by Django 1.9.3 on 2017-11-03 21:58 |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('dtys', '0001_initial'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='dtysmodel', |
||||
name='is_ordered', |
||||
field=models.BooleanField(default=False, verbose_name='Заказан'), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='dtysmodel', |
||||
name='end_date', |
||||
field=models.DateField(verbose_name='Дата окончания'), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='dtysmodel', |
||||
name='end_time', |
||||
field=models.TimeField(verbose_name='Время окончания'), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='dtysmodel', |
||||
name='is_public', |
||||
field=models.BooleanField(default=False, verbose_name='Опубликован'), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='dtysmodel', |
||||
name='is_stopped', |
||||
field=models.BooleanField(default=False, verbose_name='Остановлен'), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='dtysmodel', |
||||
name='price_end', |
||||
field=models.IntegerField(verbose_name='Конечная цена (минимальная)'), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='dtysmodel', |
||||
name='price_start', |
||||
field=models.IntegerField(verbose_name='Начальная цена'), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='dtysmodel', |
||||
name='price_stopped', |
||||
field=models.IntegerField(default=0, verbose_name='Прайс заказа'), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='dtysmodel', |
||||
name='start_date', |
||||
field=models.DateField(verbose_name='Дата начала'), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='dtysmodel', |
||||
name='start_time', |
||||
field=models.TimeField(verbose_name='Время начала'), |
||||
), |
||||
] |
||||
@ -0,0 +1,95 @@ |
||||
from datetime import datetime |
||||
|
||||
from django.db import models |
||||
from store.models import ProductVariation |
||||
|
||||
|
||||
def get_change(current, previous): |
||||
if current == previous: |
||||
return 100.0 |
||||
try: |
||||
return (abs(current - previous) / previous) * 100.0 |
||||
except ZeroDivisionError: |
||||
return 0 |
||||
|
||||
|
||||
class DTYSModel(models.Model): |
||||
"""Drop `Til You Shop Model""" |
||||
|
||||
product = models.ForeignKey(ProductVariation) |
||||
|
||||
price_start = models.IntegerField(verbose_name="Начальная цена") |
||||
price_end = models.IntegerField(verbose_name="Конечная цена (минимальная)") |
||||
price_stopped = models.IntegerField(verbose_name="Прайс заказа", default=0) |
||||
|
||||
start_date = models.DateField(verbose_name='Дата начала') |
||||
start_time = models.TimeField(verbose_name='Время начала') |
||||
|
||||
end_date = models.DateField(verbose_name='Дата окончания') |
||||
end_time = models.TimeField(verbose_name='Время окончания') |
||||
|
||||
is_stopped = models.BooleanField(verbose_name="Остановлен", default=False) |
||||
is_public = models.BooleanField(verbose_name="Опубликован", default=False) |
||||
is_ordered = models.BooleanField(verbose_name="Заказан", default=False) |
||||
|
||||
class Meta: |
||||
verbose_name = "Счётчик цены" |
||||
verbose_name_plural = "Счётчики цен" |
||||
|
||||
@property |
||||
def end_datetime(self): |
||||
return datetime.combine(self.end_date, self.end_time) |
||||
|
||||
@property |
||||
def start_datetime(self): |
||||
return datetime.combine(self.start_date, self.start_time) |
||||
|
||||
def get_dec_by_sec(self): |
||||
return "%.1f" % (self.get_price_diff() / self.get_date_delta()) |
||||
|
||||
def get_price_diff(self): |
||||
return self.price_start - self.price_end |
||||
|
||||
def _time_percent(self): |
||||
time_percent = get_change( |
||||
self.get_delta_now(), |
||||
self.get_date_delta() |
||||
) |
||||
return time_percent |
||||
|
||||
def get_delta_now(self): |
||||
"""in seconds""" |
||||
from django.utils import timezone as tz |
||||
_now = tz.now() |
||||
return (self.end_datetime - _now).total_seconds() |
||||
|
||||
def get_date_delta(self): |
||||
""" in seconds """ |
||||
return (self.end_datetime - self.start_datetime).total_seconds() |
||||
|
||||
def get_current_price(self): |
||||
dec_from_price = (self.get_price_diff() * (self._time_percent() / 100)) |
||||
price_current = self.price_start - dec_from_price |
||||
|
||||
return price_current |
||||
|
||||
def current_price_format(self): |
||||
return "%.1f" % self.get_current_price() |
||||
|
||||
def stop(self): |
||||
"""Stop this DTYS""" |
||||
self.is_stopped = True |
||||
|
||||
if self.price_stopped == 0: |
||||
self.price_stopped = max(self.price_end, self.get_current_price()) |
||||
|
||||
self.save() |
||||
|
||||
def save(self, *args, **kwargs): |
||||
if not self.id: |
||||
pass |
||||
|
||||
ProductVariation.objects.filter(id=self.product.id)\ |
||||
.update(has_discount=False) |
||||
|
||||
super(DTYSModel, self).save(*args, **kwargs) |
||||
@ -0,0 +1,2 @@ |
||||
celery=4.1.0 |
||||
redis |
||||
@ -0,0 +1,11 @@ |
||||
from celery import task |
||||
|
||||
# app = Celery('tasks', broker='redis://localhost:6379/0') |
||||
|
||||
|
||||
@task |
||||
def return_dtys(dtys_id): |
||||
from .models import DTYSModel |
||||
|
||||
DTYSModel.objects.filter(id=dtys_id, is_ordered=False)\ |
||||
.update(is_stopped=False, price_stopped=0) |
||||
@ -0,0 +1,3 @@ |
||||
from django.test import TestCase |
||||
|
||||
# Create your tests here. |
||||
@ -0,0 +1,12 @@ |
||||
from django.conf.urls import patterns, url |
||||
|
||||
from .views import DTYSListView, DTYSInfoView, DTYSBuyView, dtys_modified |
||||
|
||||
|
||||
urlpatterns = patterns( |
||||
'', |
||||
url(r'^$', DTYSListView.as_view()), |
||||
url(r'^updates$', dtys_modified), |
||||
url(r'^info/$', DTYSInfoView.as_view()), |
||||
url(r'^buy/(?P<pk>\d+)/$', DTYSBuyView.as_view()) |
||||
) |
||||
@ -0,0 +1,165 @@ |
||||
import os |
||||
|
||||
from django.conf import settings |
||||
from django.http import ( |
||||
Http404, |
||||
HttpResponse, |
||||
HttpResponseRedirect, |
||||
JsonResponse, |
||||
) |
||||
from django.core.cache import cache |
||||
from django.utils import timezone |
||||
from django.views.decorators.http import etag |
||||
from django.views.generic import View, ListView, DetailView |
||||
|
||||
from .models import DTYSModel |
||||
|
||||
import logging |
||||
|
||||
log = logging.getLogger(__name__) |
||||
|
||||
|
||||
DTYS_UPDATE_FILE = os.path.join(settings.MEDIA_ROOT, "dtys_update") |
||||
|
||||
|
||||
def update_dtys_etag(): |
||||
fhandle = open(DTYS_UPDATE_FILE, 'a') |
||||
|
||||
try: |
||||
os.utime(DTYS_UPDATE_FILE, None) |
||||
except FileNotFoundError: |
||||
open(DTYS_UPDATE_FILE, 'a').close() |
||||
finally: |
||||
fhandle.close() |
||||
|
||||
|
||||
def latest_entry(request): |
||||
DTYSModel.objects.filter( |
||||
end_date__lte=timezone.now().date(), |
||||
end_time__lte=timezone.now().time() |
||||
).update(is_stopped=True) |
||||
|
||||
d = DTYSModel.objects.filter( |
||||
is_public=True, |
||||
is_stopped=False |
||||
) |
||||
|
||||
if d.count() != cache.get("dtysETAGCount"): |
||||
cache.set("dtysETAGCount", d.count()) |
||||
update_dtys_etag() |
||||
|
||||
if not os.path.exists(DTYS_UPDATE_FILE): |
||||
update_dtys_etag() |
||||
|
||||
modified = str(os.path.getmtime(DTYS_UPDATE_FILE)) |
||||
|
||||
return modified |
||||
|
||||
|
||||
@etag(latest_entry) |
||||
def dtys_modified(request): |
||||
return HttpResponse('') |
||||
|
||||
|
||||
class DTYSListView(ListView): |
||||
model = DTYSModel |
||||
template_name = "dtys/index.jinja" |
||||
|
||||
def get_queryset(self, *args, **kwargs): |
||||
qs = super(DTYSListView, self).get_queryset(*args, **kwargs) |
||||
qs = qs.filter( |
||||
is_public=True, |
||||
start_date__lte=timezone.now().date(), |
||||
end_date__gte=timezone.now().date(), |
||||
start_time__lte=timezone.now().time(), |
||||
end_time__gte=timezone.now().time() |
||||
) |
||||
if qs.count() == 0: |
||||
raise Http404() |
||||
|
||||
return qs |
||||
|
||||
|
||||
class DTYSBuyView(DetailView): |
||||
model = DTYSModel |
||||
|
||||
def get_queryset(self, *args, **kwargs): |
||||
qs = super(DTYSBuyView, self).get_queryset(*args, **kwargs) |
||||
qs = qs.filter( |
||||
is_public=True, |
||||
start_date__lte=timezone.now().date(), |
||||
end_date__gte=timezone.now().date(), |
||||
start_time__lte=timezone.now().time(), |
||||
end_time__gte=timezone.now().time() |
||||
) |
||||
|
||||
if qs.count() == 0: |
||||
raise Http404() |
||||
|
||||
return qs |
||||
|
||||
def get(self, request, *args, **kwargs): |
||||
obj = self.get_object() |
||||
|
||||
log.debug(obj.id) |
||||
|
||||
if obj.is_public and not obj.is_stopped: |
||||
from store.cart import Cart, CartItem |
||||
from store.models import ProductVariation |
||||
from .tasks import return_dtys |
||||
|
||||
update_dtys_etag() |
||||
|
||||
# stop DTYS for this product |
||||
obj.stop() |
||||
|
||||
ProductVariation.objects.filter(id=obj.product.id)\ |
||||
.update(price=obj.price_stopped) |
||||
obj.product.price = int(obj.price_stopped) |
||||
obj.product.save() |
||||
|
||||
# Add to cart |
||||
cart = Cart(self.request) |
||||
|
||||
cart.add_item(CartItem(obj.product, 1)) |
||||
|
||||
return_dtys.apply_async( |
||||
(obj.id, ), countdown=settings.RESUME_DTYS_DELAY_SECONDS) |
||||
|
||||
return HttpResponseRedirect('/store/cart/') |
||||
|
||||
return HttpResponseRedirect('/dtys/') |
||||
|
||||
|
||||
class DTYSInfoView(View): |
||||
"""Ajax info""" |
||||
|
||||
def get(self, request): |
||||
data = { |
||||
"dtys_list": [] |
||||
} |
||||
|
||||
dtys_list = DTYSModel.objects.filter( |
||||
is_public=True, |
||||
start_date__lte=timezone.now(), |
||||
end_date__gte=timezone.now(), |
||||
start_time__lte=timezone.now().time() |
||||
) |
||||
|
||||
for i in dtys_list: |
||||
if i.end_time <= timezone.now().time(): |
||||
i.stop() |
||||
|
||||
dtys_item = { |
||||
'id': i.id, |
||||
'stopped': i.is_stopped, |
||||
'stopped_price': i.price_stopped |
||||
} |
||||
|
||||
if not i.is_stopped: |
||||
dtys_item['current_price'] = i.current_price_format() |
||||
dtys_item['price_dec_in_sec'] = i.get_dec_by_sec() |
||||
|
||||
data['dtys_list'].append(dtys_item) |
||||
|
||||
return JsonResponse(data) |
||||
@ -0,0 +1,3 @@ |
||||
#!/bin/bash |
||||
|
||||
celery -A batiskaf worker --loglevel=info >> celery.log & |
||||
@ -0,0 +1,162 @@ |
||||
function getCookie(name) { |
||||
var cookieValue = null; |
||||
if (document.cookie && document.cookie !== '') { |
||||
var cookies = document.cookie.split(';'); |
||||
for (var i = 0; i < cookies.length; i++) { |
||||
var cookie = cookies[i]; |
||||
// Does this cookie string begin with the name we want?
|
||||
if (cookie.substring(0, name.length + 1) === (name + '=')) { |
||||
cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
return cookieValue; |
||||
} |
||||
|
||||
function countdownPrice(el, beginValue, decInSecond) { |
||||
var counter = el.find(".counter"); |
||||
|
||||
counter.text(beginValue); |
||||
|
||||
if (el.attr("data-tid") ) { |
||||
var tid = el.attr("data-tid") |
||||
clearInterval(tid); |
||||
} |
||||
|
||||
var delay = 1000; |
||||
var div = 2.0; |
||||
|
||||
var timerId = setInterval(function(){ |
||||
var val = parseFloat(counter.text()); |
||||
var new_val = (val - (decInSecond / div)).toFixed(); |
||||
counter.text(new_val); |
||||
}, delay / div); |
||||
|
||||
el.attr("data-tid", timerId); |
||||
} |
||||
|
||||
function countdownPriceStop(el) { |
||||
clearInterval(el.attr("data-tid")); |
||||
} |
||||
|
||||
function get_price() { |
||||
$.ajax({ |
||||
url: "/dtys/info/", |
||||
method: "GET", |
||||
success: function(data, textStatus, jqXHR) { |
||||
console.log(data); |
||||
|
||||
if (data.dtys_list.length > 0) { |
||||
var active = data.dtys_list; |
||||
|
||||
active.forEach(function(i, idx, list) { |
||||
var product = $("#dtys_product_" + i.id); |
||||
var add_to_cart_btn = product.find(".add-to-cart"); |
||||
var fake_add_to_cart_btn = product.find(".fake-add-to-cart"); |
||||
|
||||
if (i.stopped) { |
||||
product.addClass("stopped"); |
||||
fake_add_to_cart_btn.show(); |
||||
add_to_cart_btn.hide(); |
||||
|
||||
product.find('.price').text(i.stopped_price); |
||||
|
||||
countdownPriceStop(product); |
||||
} else { |
||||
product.removeClass("stopped"); |
||||
product.find(".price").text(i.current_price); |
||||
fake_add_to_cart_btn.hide(); |
||||
add_to_cart_btn.show(); |
||||
|
||||
countdownPrice(product, i.current_price, i.price_dec_in_sec); |
||||
} |
||||
}); |
||||
} |
||||
}, |
||||
error: function(jqXHR, textStatus, errorThrow) { |
||||
console.log("что-то пошло не так, сервер не отвечает"); |
||||
} |
||||
}); |
||||
}; |
||||
|
||||
var Updater = function(){ |
||||
this.params = { |
||||
period: 3000, |
||||
url: '', |
||||
onModified: function(data,x,modified){}, |
||||
bgPause: false |
||||
}; |
||||
|
||||
this.interval = null; |
||||
this.ETag = ''; |
||||
this.lastModified = ''; |
||||
|
||||
this.init = function(params){ |
||||
var me = this; |
||||
this.params = $.extend(this.params, params); |
||||
|
||||
if(this.params.bgPause){ |
||||
$(window).blur(function(){ me.pause() }); |
||||
$(window).focus(function(){ me.resume() }); |
||||
} |
||||
}; |
||||
|
||||
this.start = function(){ |
||||
var me = this; |
||||
this.interval = setInterval(function(){ me.doUpdate() }, this.params.period); |
||||
}; |
||||
|
||||
this.doUpdate = function() { |
||||
var me = this; |
||||
$.ajax(this.params.url, { |
||||
success: function(data,status,x){ |
||||
$(".dtys__product").each(function(){ |
||||
$(this).removeClass("wait"); |
||||
}); |
||||
|
||||
if(me.ETag != x.getResponseHeader('ETag')){ |
||||
me.params.onModified(data,x,me.lastModified); |
||||
me.lastModified = x.getResponseHeader('Last-Modified'); |
||||
} |
||||
me.ETag = x.getResponseHeader('ETag'); |
||||
}, |
||||
error: function(jqXHR, textStatus, errorThrown) { |
||||
$(".dtys__product").each(function(){ |
||||
$(this).addClass("wait"); |
||||
countdownPriceStop($(this)); |
||||
}); |
||||
}, |
||||
beforeSend: function(x){ |
||||
if(me.ETag != '') { x.setRequestHeader('If-None-Match', me.ETag); } |
||||
}, |
||||
cache: false |
||||
}); |
||||
}; |
||||
|
||||
this.pause = function(){ |
||||
clearInterval(this.interval); |
||||
this.interval = null; |
||||
}; |
||||
|
||||
this.resume = function(){ |
||||
if(this.interval != null) return; |
||||
this.start(); |
||||
this.doUpdate(); |
||||
}; |
||||
}; |
||||
|
||||
$(function(){ |
||||
var upd = new Updater(); |
||||
|
||||
get_price(); |
||||
|
||||
upd.init({ |
||||
url: "/dtys/updates", |
||||
onModified: function(data, x, modified) { |
||||
get_price(); |
||||
} |
||||
}); |
||||
|
||||
upd.start(); |
||||
}); |
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,19 @@ |
||||
# -*- coding: utf-8 -*- |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import models, migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('store', '0044_auto_20151223_1612'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AlterField( |
||||
model_name='orderdata', |
||||
name='deliv_type', |
||||
field=models.CharField(max_length=2, blank=True, verbose_name='Способ Алемтат', choices=[('E', 'Экспресс-отправления по РК'), ('T', 'Не срочные отправления по РК')], null=True, default=''), |
||||
), |
||||
] |
||||
@ -0,0 +1,15 @@ |
||||
# -*- coding: utf-8 -*- |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import models, migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('store', '0045_auto_20160107_1403'), |
||||
('store', '0045_auto_20151223_1646'), |
||||
] |
||||
|
||||
operations = [ |
||||
] |
||||
@ -0,0 +1,15 @@ |
||||
# -*- coding: utf-8 -*- |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import models, migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('store', '0046_merge'), |
||||
('store', '0046_auto_20160202_1121'), |
||||
] |
||||
|
||||
operations = [ |
||||
] |
||||
@ -0,0 +1,15 @@ |
||||
# -*- coding: utf-8 -*- |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import models, migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('store', '0047_merge'), |
||||
('store', '0047_auto_20160229_1409'), |
||||
] |
||||
|
||||
operations = [ |
||||
] |
||||
@ -0,0 +1,15 @@ |
||||
# -*- coding: utf-8 -*- |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import models, migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('store', '0048_auto_20160302_0839'), |
||||
('store', '0048_merge'), |
||||
] |
||||
|
||||
operations = [ |
||||
] |
||||
@ -0,0 +1,16 @@ |
||||
# -*- coding: utf-8 -*- |
||||
# Generated by Django 1.9.3 on 2016-03-07 20:44 |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('store', '0049_merge'), |
||||
('store', '0049_auto_20160307_2043'), |
||||
] |
||||
|
||||
operations = [ |
||||
] |
||||
@ -0,0 +1,16 @@ |
||||
# -*- coding: utf-8 -*- |
||||
# Generated by Django 1.9.3 on 2016-03-12 16:33 |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('store', '0050_merge'), |
||||
('store', '0050_auto_20160312_1628'), |
||||
] |
||||
|
||||
operations = [ |
||||
] |
||||
@ -0,0 +1,16 @@ |
||||
# -*- coding: utf-8 -*- |
||||
# Generated by Django 1.9.3 on 2016-03-14 11:41 |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('store', '0051_cartmodel'), |
||||
('store', '0051_merge'), |
||||
] |
||||
|
||||
operations = [ |
||||
] |
||||
@ -0,0 +1,16 @@ |
||||
# -*- coding: utf-8 -*- |
||||
# Generated by Django 1.9.3 on 2016-04-04 10:33 |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('store', '0053_productvariation_delivery_date'), |
||||
('store', '0052_merge'), |
||||
] |
||||
|
||||
operations = [ |
||||
] |
||||
@ -0,0 +1,16 @@ |
||||
# -*- coding: utf-8 -*- |
||||
# Generated by Django 1.9.3 on 2016-07-15 19:20 |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('store', '0054_merge'), |
||||
('store', '0054_auto_20160715_1811'), |
||||
] |
||||
|
||||
operations = [ |
||||
] |
||||
@ -0,0 +1,16 @@ |
||||
# -*- coding: utf-8 -*- |
||||
# Generated by Django 1.9.3 on 2017-03-07 15:49 |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('store', '0057_auto_20170306_1933'), |
||||
('store', '0055_merge'), |
||||
] |
||||
|
||||
operations = [ |
||||
] |
||||
@ -0,0 +1,16 @@ |
||||
# -*- coding: utf-8 -*- |
||||
# Generated by Django 1.9.3 on 2017-05-07 02:57 |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('store', '0059_auto_20170506_1116'), |
||||
('store', '0058_merge'), |
||||
] |
||||
|
||||
operations = [ |
||||
] |
||||
@ -0,0 +1,25 @@ |
||||
# -*- coding: utf-8 -*- |
||||
# Generated by Django 1.9.3 on 2017-06-03 02:27 |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('store', '0060_merge'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AlterField( |
||||
model_name='orderdata', |
||||
name='city', |
||||
field=models.CharField(blank=True, max_length=20, null=True, verbose_name='Город Алемтат'), |
||||
), |
||||
migrations.AlterField( |
||||
model_name='orderdata', |
||||
name='deliv_type', |
||||
field=models.CharField(blank=True, default='', max_length=2, null=True, verbose_name='Способ Алемтат'), |
||||
), |
||||
] |
||||
@ -0,0 +1,16 @@ |
||||
# -*- coding: utf-8 -*- |
||||
# Generated by Django 1.9.3 on 2017-06-03 02:28 |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('store', '0061_auto_20170603_0220'), |
||||
('store', '0061_auto_20170603_0227'), |
||||
] |
||||
|
||||
operations = [ |
||||
] |
||||
@ -0,0 +1,20 @@ |
||||
# -*- coding: utf-8 -*- |
||||
# Generated by Django 1.9.3 on 2017-11-07 16:56 |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('store', '0061_auto_20170603_0220'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='productvariation', |
||||
name='has_discount', |
||||
field=models.BooleanField(default=True, help_text='Если не указано, то скидка при расчёте цены не учитывается', verbose_name='Со скидкой'), |
||||
), |
||||
] |
||||
@ -0,0 +1,16 @@ |
||||
# -*- coding: utf-8 -*- |
||||
# Generated by Django 1.9.3 on 2017-11-07 18:10 |
||||
from __future__ import unicode_literals |
||||
|
||||
from django.db import migrations |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('store', '0062_productvariation_has_discount'), |
||||
('store', '0062_merge'), |
||||
] |
||||
|
||||
operations = [ |
||||
] |
||||
Loading…
Reference in new issue