diff --git a/api/v1/serializers/course.py b/api/v1/serializers/course.py
index d1e8dcba..bdb1a289 100644
--- a/api/v1/serializers/course.py
+++ b/api/v1/serializers/course.py
@@ -184,6 +184,7 @@ class LessonCreateSerializer(DispatchContentMixin, serializers.ModelSerializer):
'created_at',
'update_at',
'deactivated_at',
+ 'position',
)
read_only_fields = (
@@ -196,6 +197,9 @@ class LessonCreateSerializer(DispatchContentMixin, serializers.ModelSerializer):
def create(self, validated_data):
content = validated_data.pop('content', [])
lesson = super().create(validated_data)
+ if not validated_data.get('position'):
+ lesson.set_last_position()
+ lesson.save()
self.dispatch_content(lesson, content)
return lesson
@@ -226,6 +230,7 @@ class LessonSerializer(serializers.ModelSerializer):
'created_at',
'update_at',
'deactivated_at',
+ 'position',
)
read_only_fields = (
diff --git a/apps/course/migrations/0039_lesson_position.py b/apps/course/migrations/0039_lesson_position.py
new file mode 100644
index 00000000..7a26d8e5
--- /dev/null
+++ b/apps/course/migrations/0039_lesson_position.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.0.6 on 2018-07-02 13:45
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('course', '0038_lesson_author'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='lesson',
+ name='position',
+ field=models.PositiveSmallIntegerField(default=1, verbose_name='Положение на странице'),
+ ),
+ ]
diff --git a/apps/course/models.py b/apps/course/models.py
index 7d0300c7..942a0593 100644
--- a/apps/course/models.py
+++ b/apps/course/models.py
@@ -177,10 +177,18 @@ class Lesson(BaseModel, DeactivatedMixin):
)
created_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
+ position = models.PositiveSmallIntegerField(
+ 'Положение на странице',
+ default=1,
+ )
def __str__(self):
return self.title
+ def set_last_position(self):
+ if self.course:
+ self.position = self.course.lessons.count()
+
def save(self, *args, **kwargs):
if not self.author and self.course and self.course.author:
self.author = self.course.author
diff --git a/apps/course/templates/course/course_only_lessons.html b/apps/course/templates/course/course_only_lessons.html
index a919e08f..f0217bcf 100644
--- a/apps/course/templates/course/course_only_lessons.html
+++ b/apps/course/templates/course/course_only_lessons.html
@@ -173,7 +173,7 @@
Содержание курса
- {% for lesson in course.lessons.all %}
+ {% for lesson in lessons %}
{% if course.author == request.user or request.user.role >= request.user.TEACHER_ROLE or paid %}
{% else %}
diff --git a/apps/course/views.py b/apps/course/views.py
index 60b7e308..8cff720a 100644
--- a/apps/course/views.py
+++ b/apps/course/views.py
@@ -214,6 +214,8 @@ class CourseView(DetailView):
status=Pingback.PINGBACK_TYPE_RISK_UNDER_REVIEW,
).exists()
context['only_lessons'] = self.only_lessons
+ if self.only_lessons:
+ context['lessons'] = self.object.lessons.order_by('position')
return context
def get_queryset(self):
diff --git a/apps/payment/admin.py b/apps/payment/admin.py
index 47dde452..19166563 100644
--- a/apps/payment/admin.py
+++ b/apps/payment/admin.py
@@ -28,10 +28,11 @@ class PaymentChildAdmin(PolymorphicChildModelAdmin):
'user',
'amount',
'status',
+ 'roistat_visit',
'created_at',
)
base_fieldsets = (
- (None, {'fields': ('user', 'amount', 'status', 'data',)}),
+ (None, {'fields': ('user', 'amount', 'status', 'data', 'roistat_visit',)}),
)
readonly_fields = ('amount', 'data',)
diff --git a/apps/payment/migrations/0019_payment_roistat_visit.py b/apps/payment/migrations/0019_payment_roistat_visit.py
new file mode 100644
index 00000000..4f7fa40e
--- /dev/null
+++ b/apps/payment/migrations/0019_payment_roistat_visit.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.0.7 on 2018-07-06 07:53
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('payment', '0018_auto_20180512_1202'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='payment',
+ name='roistat_visit',
+ field=models.PositiveIntegerField(editable=False, null=True, verbose_name='Номер визита Roistat'),
+ ),
+ ]
diff --git a/apps/payment/models.py b/apps/payment/models.py
index b1368dc4..32d7a0e9 100644
--- a/apps/payment/models.py
+++ b/apps/payment/models.py
@@ -97,6 +97,7 @@ class Payment(PolymorphicModel):
amount = models.DecimalField('Итого', max_digits=8, decimal_places=2, default=0, editable=False)
status = models.PositiveSmallIntegerField('Статус платежа', choices=PW_STATUS_CHOICES, null=True)
data = JSONField('Данные платежа от провайдера', default={}, editable=False)
+ roistat_visit = models.PositiveIntegerField('Номер визита Roistat', null=True, editable=False)
created_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
diff --git a/apps/payment/tasks.py b/apps/payment/tasks.py
index 911235a3..e30f4e19 100644
--- a/apps/payment/tasks.py
+++ b/apps/payment/tasks.py
@@ -38,12 +38,13 @@ def product_payment_to_mixpanel(user_id, event_name, time, properties):
@app.task
-def transaction_to_roistat(user_id, payment_id, event_name, amount, time, status, product_type):
+def transaction_to_roistat(user_id, payment_id, event_name, amount, time, status, product_type, roistat_visit):
body = [{
'id': str(payment_id),
'name': event_name,
'date_create': time,
'status': str(status),
+ 'roistat': str(roistat_visit) if roistat_visit else None,
'price': str(amount),
'client_id': str(user_id),
'fields': {
diff --git a/apps/payment/views.py b/apps/payment/views.py
index 34d35a0b..4f4a958a 100644
--- a/apps/payment/views.py
+++ b/apps/payment/views.py
@@ -58,12 +58,14 @@ class CourseBuyView(TemplateView):
host = urlsplit(self.request.META.get('HTTP_REFERER'))
host = str(host[0]) + '://' + str(host[1])
course = Course.objects.get(id=pk)
+ roistat_visit = request.COOKIES.get('roistat_visit', None)
if request.user == course.author:
messages.error(request, 'Вы не можете приобрести свой курс.')
return redirect(reverse_lazy('course', args=[course.id]))
course_payment = CoursePayment.objects.create(
user=request.user,
course=course,
+ roistat_visit=roistat_visit,
)
product = Product(
f'course_{course_payment.id}',
@@ -96,6 +98,7 @@ class SchoolBuyView(TemplateView):
host = str(host[0]) + '://' + str(host[1])
weekdays = set(request.GET.getlist('weekdays', []))
add_days = 'add_days' in request.GET
+ roistat_visit = request.COOKIES.get('roistat_visit', None)
if not weekdays:
messages.error(request, 'Выберите несколько дней недели.')
return redirect('school:summer-school')
@@ -117,6 +120,7 @@ class SchoolBuyView(TemplateView):
date_start=now().date(),
date_end=_school_payment.date_end,
add_days=True,
+ roistat_visit=roistat_visit,
)
if school_payment.amount <= 0:
messages.error(request, 'Выбранные дни отсутствуют в оставшемся периоде подписки')
@@ -125,6 +129,7 @@ class SchoolBuyView(TemplateView):
school_payment = SchoolPayment.objects.create(
user=request.user,
weekdays=weekdays,
+ roistat_visit=roistat_visit,
)
product = Product(
f'school_{school_payment.id}',
@@ -259,6 +264,7 @@ class PaymentwallCallbackView(View):
now().strftime('%Y-%m-%d %H:%M:%S'),
pingback.get_type(),
product_type_name,
+ payment.roistat_visit,
)
author_balance = getattr(payment, 'author_balance', None)
if author_balance and author_balance.type == AuthorBalance.IN:
diff --git a/project/templates/lilcity/index.html b/project/templates/lilcity/index.html
index 30b5541a..5d7b9d2d 100644
--- a/project/templates/lilcity/index.html
+++ b/project/templates/lilcity/index.html
@@ -76,7 +76,44 @@
&noscript=1"/>
-
+
+
+
+
+
+
+
{% include "templates/blocks/mixpanel.html" %}
diff --git a/requirements.txt b/requirements.txt
index e1b351e6..05894ddd 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,27 +1,26 @@
# Python-3.6
arrow==0.12.1
celery[redis]==4.2.0
-Django==2.0.6
+Django==2.0.7
django-active-link==0.1.5
django-anymail[mailgun]==3.0
django-cors-headers==2.3.0
django_compressor==2.2
django-filter==2.0.0.dev1
django-mptt==0.9.0
-django-silk==3.0.0
django-phonenumber-field==2.0.0
django-polymorphic-tree==1.5
djangorestframework==3.8.2
-drf-yasg[validation]==1.9.0
+drf-yasg==1.9.0
facepy==1.0.9
-gunicorn==19.8.1
+gunicorn==19.9.0
mixpanel==4.3.2
psycopg2-binary==2.7.5
-Pillow==5.1.0
+Pillow==5.2.0
raven==6.9.0
requests==2.19.1
sorl-thumbnail==12.4.1
-twilio==6.14.6
+twilio==6.14.7
# paymentwall-python==1.0.7
git+https://github.com/ivlevdenis/paymentwall-python.git
# python-instagram==1.3.2
diff --git a/web/src/components/CourseRedactor.vue b/web/src/components/CourseRedactor.vue
index 3ba9359e..f4291156 100644
--- a/web/src/components/CourseRedactor.vue
+++ b/web/src/components/CourseRedactor.vue
@@ -215,24 +215,31 @@
Содержание курса
-
-
-
-
-
-
{{ lesson.title }}
-
-
{{ lesson.short_description }}
-
-
+
+
+
+
+
+
+
+
{{ lesson.title }}
+
+
{{ lesson.short_description }}
+
+
+
Загрузка...