From 4ba2b3f115e3d6a5d11ea490a7b2e564fd95c897 Mon Sep 17 00:00:00 2001 From: gzbender Date: Fri, 12 Oct 2018 22:34:11 +0500 Subject: [PATCH 01/20] =?UTF-8?q?LIL-679=20=D0=A3=D0=B1=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D1=8C=20=D0=B4=D0=B0=D1=82=D1=83=20"=D0=BA=D0=BE=D0=B3=D0=B4?= =?UTF-8?q?=D0=B0=20=D0=BA=D1=83=D1=80=D1=81=20=D0=B7=D0=B0=D0=B2=D0=B5?= =?UTF-8?q?=D0=B4=D0=B5=D0=BD"=20=D0=BD=D0=B0=20=D1=81=D0=B0=D0=B9=D1=82?= =?UTF-8?q?=D0=B5=20=D0=B2=20=D0=BA=D1=83=D1=80=D1=81=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/course/templates/course/course.html | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/course/templates/course/course.html b/apps/course/templates/course/course.html index bfed806a..5b86502b 100644 --- a/apps/course/templates/course/course.html +++ b/apps/course/templates/course/course.html @@ -112,8 +112,6 @@
{{ course.price|floatformat:"-2" }}₽
{% endif %} - -
From 6767f69a902187587c8c881b5cf8b1cd8bbcc41b Mon Sep 17 00:00:00 2001 From: gzbender Date: Wed, 24 Oct 2018 19:52:27 +0500 Subject: [PATCH 02/20] LIL-679 --- apps/course/templates/course/course.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/course/templates/course/course.html b/apps/course/templates/course/course.html index 5b86502b..a0fe6e14 100644 --- a/apps/course/templates/course/course.html +++ b/apps/course/templates/course/course.html @@ -100,7 +100,7 @@
-
{{ course.duration | rupluralize:"день,дня,дней" }}
+ {{ course.duration | rupluralize:"день,дня,дней" }}
{% if course.price %}
From d891c7089cffec8d9fdd3da82b1bb032fc14a90a Mon Sep 17 00:00:00 2001 From: gzbender Date: Wed, 24 Oct 2018 22:44:08 +0500 Subject: [PATCH 03/20] =?UTF-8?q?LIL-704=20=D0=9F=D0=BE=D1=87=D0=B8=D0=BD?= =?UTF-8?q?=D0=B8=D1=82=D1=8C=20=D0=B2=D1=8B=D0=BF=D0=B0=D0=B4=D0=B0=D1=8E?= =?UTF-8?q?=D1=89=D0=B8=D0=B9=20=D1=81=D0=BF=D0=B8=D1=81=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/v1/serializers/course.py | 19 +++++-------------- api/v1/views.py | 21 +++++++++++++++++---- requirements.txt | 1 + 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/api/v1/serializers/course.py b/api/v1/serializers/course.py index 551830ad..781af25e 100644 --- a/api/v1/serializers/course.py +++ b/api/v1/serializers/course.py @@ -1,9 +1,8 @@ +from django.contrib.auth import get_user_model from ipware import get_client_ip - from rest_framework import serializers from rest_framework.validators import UniqueValidator - -from django.contrib.auth import get_user_model +from drf_dynamic_fields import DynamicFieldsMixin from apps.course.models import ( Category, Course, @@ -13,17 +12,9 @@ from apps.course.models import ( LiveLessonComment) from .content import ( ImageObjectSerializer, ContentSerializer, ContentCreateSerializer, - GallerySerializer, GalleryImageSerializer, -) - -from apps.content.models import ( - Content, Image, Text, ImageText, Video, - Gallery, GalleryImage, ImageObject, - ContestWork) - -from .user import UserSerializer + GallerySerializer, ) from .mixins import DispatchContentMixin, DispatchGalleryMixin, DispatchMaterialMixin - +from .user import UserSerializer User = get_user_model() @@ -269,7 +260,7 @@ class LessonSerializer(serializers.ModelSerializer): ) -class CourseSerializer(serializers.ModelSerializer): +class CourseSerializer(DynamicFieldsMixin, serializers.ModelSerializer): author = UserSerializer() category = CategorySerializer() materials = MaterialSerializer(many=True) diff --git a/api/v1/views.py b/api/v1/views.py index f792972b..744ab371 100644 --- a/api/v1/views.py +++ b/api/v1/views.py @@ -18,7 +18,7 @@ from .serializers.course import ( MaterialSerializer, MaterialCreateSerializer, LessonSerializer, LessonCreateSerializer, LikeCreateSerializer, CourseCommentSerializer, LessonCommentSerializer, - LiveLessonCommentSerializer) + LiveLessonCommentSerializer,) from .serializers.content import ( BanerSerializer, ImageSerializer, ImageCreateSerializer, @@ -36,8 +36,7 @@ from .serializers.school import ( ) from .serializers.payment import ( AuthorBalanceSerializer, AuthorBalanceCreateSerializer, - PaymentSerializer, CoursePaymentSerializer, - SchoolPaymentSerializer, + PaymentSerializer, CoursePaymentCreateSerializer, SchoolPaymentCreateSerializer) from .serializers.user import ( AuthorRequestSerializer, @@ -48,7 +47,7 @@ from .serializers.contest import ( ) from .permissions import ( - IsAdmin, IsAdminOrIsSelf, + IsAdmin, IsAuthorOrAdmin, IsAuthorObjectOrAdmin, IsTeacherOrAdmin, ) @@ -240,6 +239,20 @@ class CourseViewSet(ExtendedModelViewSet): # 'delete': IsAdmin, # } + def list(self, request, *args, **kwargs): + queryset = self.filter_queryset(self.get_queryset()) + + if request.query_params.get('page'): + page = self.paginate_queryset(queryset) + if page is not None: + serializer = self.get_serializer(page, many=True) + return self.get_paginated_response(serializer.data) + else: + return Response({'results': []}) + + serializer = self.get_serializer(queryset, many=True) + return Response(serializer.data) + @list_route(methods=['get']) def draft(self, request): drafts = Course.objects.filter(author=request.user, status=Course.DRAFT) diff --git a/requirements.txt b/requirements.txt index 052bb32e..27daa65a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,3 +33,4 @@ django-imagekit pusher==2.0.1 short_url sendgrid +drf_dynamic_fields From 6cadaaf64fedfe8c7654cfc0a313ac89407f6b7c Mon Sep 17 00:00:00 2001 From: gzbender Date: Wed, 24 Oct 2018 23:44:45 +0500 Subject: [PATCH 04/20] =?UTF-8?q?LIL-700=20=D0=A3=D0=B1=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D1=8C=20=D1=85=D1=80=D0=BE=D0=BD=D0=BE=D1=81=D1=87=D0=B5=D1=82?= =?UTF-8?q?=D1=87=D0=B8=D0=BA=20(=D0=B4=D0=B0=D0=B2=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D1=8C=20=D0=BF=D1=83=D0=B1=D0=BB=D0=B8=D0=BA=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B8=20=D0=BA=D1=83=D1=80=D1=81=D0=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/course/templates/course/_items.html | 1 - apps/course/templates/course/course.html | 24 ++++--------------- .../templates/course/course_only_lessons.html | 17 ++----------- apps/course/templates/course/lesson.html | 3 --- web/src/sass/_common.sass | 5 ++-- 5 files changed, 10 insertions(+), 40 deletions(-) diff --git a/apps/course/templates/course/_items.html b/apps/course/templates/course/_items.html index 0bb7c7d2..ff72a87d 100644 --- a/apps/course/templates/course/_items.html +++ b/apps/course/templates/course/_items.html @@ -73,7 +73,6 @@
{{ course.author.get_full_name }}
-
{{ course.created_at_humanize }}
{% data_liked user course as liked %}
- +
{{ course.duration | rupluralize:"день,дня,дней" }}
+ {% if course.price %}
@@ -279,30 +276,19 @@ {% endif %}
{{ course.author.get_full_name }}
-
-
{{ course.created_at_humanize }}
-
- -
-
- - - -
-
{{ course.created_at | date:"d F Yг." }}
-
+
{% if course.price %}
diff --git a/apps/course/templates/course/course_only_lessons.html b/apps/course/templates/course/course_only_lessons.html index b603874b..9aef0650 100644 --- a/apps/course/templates/course/course_only_lessons.html +++ b/apps/course/templates/course/course_only_lessons.html @@ -85,30 +85,19 @@ {% endif %}
{{ course.author.get_full_name }}
-
-
{{ course.created_at_humanize }}
-
- -
-
- - - -
-
{{ course.created_at | date:"d F Yг." }}
-
+
{% if course.price %}
@@ -119,8 +108,6 @@
{{ course.price|floatformat:"-2" }}₽
{% endif %} -
-
diff --git a/apps/course/templates/course/lesson.html b/apps/course/templates/course/lesson.html index f6fb6a9c..e4f083f0 100644 --- a/apps/course/templates/course/lesson.html +++ b/apps/course/templates/course/lesson.html @@ -47,9 +47,6 @@ {% endif %}
{{ lesson.author.get_full_name }}
-
-
{{ lesson.created_at_humanize }}
-
diff --git a/web/src/sass/_common.sass b/web/src/sass/_common.sass index 6cecc9c0..28847a1c 100755 --- a/web/src/sass/_common.sass +++ b/web/src/sass/_common.sass @@ -1058,6 +1058,7 @@ a[name] flex: 0 0 40px &__info flex: 0 0 calc(100% - 50px) + display: flex &__name, &__date +fb @@ -1065,9 +1066,8 @@ a[name] text-transform: uppercase letter-spacing: 0.5px line-height: 1.1 - &__name - margin-bottom: 5px &__meta + flex: 1 display: flex align-items: center &__date @@ -2539,6 +2539,7 @@ a.grey-link &__item display: flex align-items: center + color: inherit &__item //&:not(:last-child) margin-right: 40px From 261191562bdf47c68de6add1108e966f93e6e74c Mon Sep 17 00:00:00 2001 From: gzbender Date: Thu, 25 Oct 2018 11:13:51 +0500 Subject: [PATCH 05/20] =?UTF-8?q?LIL-680=20=D0=9F=D0=BE=D0=B4=D0=B0=D1=80?= =?UTF-8?q?=D0=BE=D1=87=D0=BD=D1=8B=D0=B5=20=D1=81=D0=B5=D1=80=D1=82=D0=B8?= =?UTF-8?q?=D1=84=D0=B8=D0=BA=D0=B0=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/payment/models.py | 8 ++++++++ apps/payment/views.py | 11 +++++++++-- project/urls.py | 1 + 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/apps/payment/models.py b/apps/payment/models.py index a953d5e8..4ac9b6b9 100644 --- a/apps/payment/models.py +++ b/apps/payment/models.py @@ -292,3 +292,11 @@ class UserBonus(models.Model): class Meta: ordering = ('created_at',) + + +class GiftCertificate(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='bonuses') + recipient = models.EmailField() + amount = models.DecimalField(max_digits=8, decimal_places=2, default=0, editable=False) + payment = models.ForeignKey(Payment, on_delete=models.SET_NULL, null=True) + bonus_sended = models.ForeignKey(UserBonus, blank=True, null=True) diff --git a/apps/payment/views.py b/apps/payment/views.py index 6be7734f..2f90259c 100644 --- a/apps/payment/views.py +++ b/apps/payment/views.py @@ -14,7 +14,7 @@ from django.contrib import messages from django.contrib.auth.decorators import login_required from django.http import HttpResponse from django.shortcuts import redirect, get_object_or_404 -from django.views.generic import View, TemplateView +from django.views.generic import View, TemplateView, DetailView from django.views.decorators.csrf import csrf_exempt from django.urls import reverse_lazy from django.utils.decorators import method_decorator @@ -27,7 +27,7 @@ from apps.course.models import Course from apps.school.models import SchoolSchedule from apps.payment.tasks import transaction_to_mixpanel, product_payment_to_mixpanel, transaction_to_roistat -from .models import AuthorBalance, CoursePayment, SchoolPayment, Payment, UserBonus +from .models import AuthorBalance, CoursePayment, SchoolPayment, Payment, UserBonus, GiftCertificate logger = logging.getLogger('django') @@ -297,3 +297,10 @@ class PaymentwallCallbackView(View): else: raise DisallowedPingbackHost return HttpResponse(status=403) + + +class GiftCertificateGetView(DetailView): + model = GiftCertificate + + def get(self): + pass diff --git a/project/urls.py b/project/urls.py index 38773131..396530cb 100644 --- a/project/urls.py +++ b/project/urls.py @@ -91,6 +91,7 @@ urlpatterns = [ path('contest//', ContestView.as_view(), name='contest'), path('contest-work//', ContestWorkView.as_view(), name='contest_work'), path('contest-work//comment', contest_work_comment, name='contest_work_comment'), + path('gift//get', ContestView.as_view(), name='contest'), ] From f95a944750fc2e40497c5ea14d5673493eae86b7 Mon Sep 17 00:00:00 2001 From: gzbender Date: Thu, 25 Oct 2018 11:55:39 +0500 Subject: [PATCH 06/20] LIL-695 --- project/templates/blocks/baner.html | 6 ++++-- web/src/sass/_common.sass | 9 ++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/project/templates/blocks/baner.html b/project/templates/blocks/baner.html index df8b81e0..4f289bce 100644 --- a/project/templates/blocks/baner.html +++ b/project/templates/blocks/baner.html @@ -1,11 +1,13 @@ {% if baner %} {% endif %}
Редактировать {% endif %} {% if not paid and course.price and not has_full_access %} - + {% if pending %}ОЖИДАЕТСЯ ПОДТВЕРЖДЕНИЕ ОПЛАТЫ{% else %}КУПИТЬ КУРС{% endif %} + {% if not paid %} + Подарить другу {% endif %} - >{% if pending %}ОЖИДАЕТСЯ ПОДТВЕРЖДЕНИЕ ОПЛАТЫ{% else %}КУПИТЬ КУРС{% endif %} +
{% endif %}
Поздравляем с успешной +

Поздравляем с успешной покупкой!

Вы получаете {{ gift_certificate.price }} лиликов на счет! 1 LIL = 1 руб.
@@ -41,10 +42,11 @@

Чтобы воспользоваться сертификатом, перейдите по ссылке
- {% url 'gift-certificate-get' gift_certificate.code %} + "> + {% setting 'MAIN_HOST' %}{% url 'index' %}?gift-certificate={{ user_gift_certificate.code }}
Или воспользуйтесь сертификатом, введя уникальный код на в разделе @@ -54,14 +56,14 @@
Ваш код
@@ -79,4 +81,35 @@ "> Вы так же можете отправить это письмо, ссылку или код вашему другу, чтобы подарить ему этот сертификат.
+
+ Присоединяйтесь к нам! +
+ + {% endblock content %} diff --git a/apps/payment/models.py b/apps/payment/models.py index 34e2765c..f7623038 100644 --- a/apps/payment/models.py +++ b/apps/payment/models.py @@ -247,12 +247,12 @@ class Payment(PolymorphicModel): else: author_balance.amount = self.amount author_balance.save() - if isinstance(self, UserGiftCertificate) and self.is_paid(): + if isinstance(self, GiftCertificatePayment) and self.is_paid(): ugs, created = UserGiftCertificate.objects.get_or_create(user=self.user, gift_certificate=self.gift_certificate, payment=self) if created: from apps.notification.tasks import send_gift_certificate - send_gift_certificate.delay(ugs) + send_gift_certificate(ugs.id) # Если юзер реферал и нет платежа, где применялась скидка if hasattr(self.user, 'referral') and not self.user.referral.payment and self.is_paid(): # Платеж - как сигнал, что скидка применилась diff --git a/apps/payment/templates/payment/gift_certificate_get.html b/apps/payment/templates/payment/gift_certificate_get.html new file mode 100644 index 00000000..0ae65e3d --- /dev/null +++ b/apps/payment/templates/payment/gift_certificate_get.html @@ -0,0 +1,14 @@ +{% extends "templates/lilcity/index.html" %} {% load static %} {% block content %} +
+
+
+
Бонусы зачислены на ваш счет!
+
Вы можете оплатить с их помощью курс или онлайн-школу
+ +
+
+
+{% endblock content %} diff --git a/apps/payment/templates/payment/gift_certificate_item.html b/apps/payment/templates/payment/gift_certificate_item.html index f77528d0..f571c1a9 100644 --- a/apps/payment/templates/payment/gift_certificate_item.html +++ b/apps/payment/templates/payment/gift_certificate_item.html @@ -10,9 +10,19 @@
{% if user_gift_certificate %} {% if user_gift_certificate.bonuses_sent %} -
Получено
+
+ + + + Получено +
{% else %} -
Ожидает получения
+
+ + + + Ожидает получения +
{% endif %} {% else %} Если вам не совсем удобно заниматься с нами каждый день в нашей онлайн-школе, специально для вас мы делаем отдельные уроки в записи, которые вы можете проходить, когда вам будет удобно.

Учите и развивайте креативное мышление когда и где угодно +
Сертификаты
diff --git a/apps/payment/views.py b/apps/payment/views.py index a25cc124..f10cc218 100644 --- a/apps/payment/views.py +++ b/apps/payment/views.py @@ -12,7 +12,7 @@ import calendar from django.contrib import messages from django.contrib.auth.decorators import login_required -from django.http import HttpResponse +from django.http import HttpResponse, Http404 from django.shortcuts import redirect, get_object_or_404 from django.views.generic import View, TemplateView, DetailView from django.views.decorators.csrf import csrf_exempt @@ -365,17 +365,25 @@ class GiftCertificateBuySuccessView(TemplateView): template_name = 'payment/gift_certificate_payment_success.html' def get(self, request, payment_id=None, *args, **kwargs): - # print(GiftCertificatePayment.objects.get(id=payment_id)) - gift_certificate_payment = get_object_or_404(GiftCertificatePayment, pk=payment_id) + try: + GiftCertificatePayment.objects.get(id=payment_id) + except: + raise Http404() return self.render_to_response(context={'gift_certificate': True}) +@method_decorator(login_required, name='dispatch') class GiftCertificateGetView(TemplateView): template_name = 'payment/gift_certificate_get.html' def get(self, request, slug, *args, **kwargs): ugs = get_object_or_404(UserGiftCertificate, pk=short_url.decode_url(slug)) - return self.render_to_response(context={'gift_certificate': ugs.gift_certificate, 'user_gift_certificate': ugs}) + if UserBonus.objects.filter(payment=ugs.payment).exists(): + raise Http404() + bonuses = UserBonus.objects.create(user=request.user, amount=ugs.gift_certificate.price, + payment=ugs.payment) + ugs.bonuses_sent = bonuses + ugs.save() + context = self.get_context_data(**kwargs) + return self.render_to_response(context) - def post(self, request, slug, *args, **kwargs): - pass diff --git a/apps/school/templates/summer/promo.html b/apps/school/templates/summer/promo.html index 8b1ed12e..7d12fac4 100644 --- a/apps/school/templates/summer/promo.html +++ b/apps/school/templates/summer/promo.html @@ -20,6 +20,9 @@ {% if is_purchased %}ваша подписка истекает {{ subscription_ends_humanize }}
перейти к оплате{% endif %}
+ {% if not is_purchased and not is_purchased_future %} + Подарить другу + {% endif %}
diff --git a/apps/user/templates/user/profile.html b/apps/user/templates/user/profile.html index 81eee428..3970b922 100644 --- a/apps/user/templates/user/profile.html +++ b/apps/user/templates/user/profile.html @@ -3,6 +3,7 @@
Редактировать + Ввести код
{% thumbnail user.photo "120x120" crop="center" as im %} @@ -91,10 +92,10 @@ Перейти в онлайн-школу
{% endif %} - {% if gift_certificates.exists %} + {% if user_gift_certificates.exists %} {% for ugs in user_gift_certificates %} {% cycle 'theme_pink2' 'theme_cyan' 'theme_violet2' as theme_color silent %} - {% include "payment/gift_certificate_item.html" gift_certificate=ugs.gift_certificate user_gift_certificate=ugs %} + {% include "payment/gift_certificate_item.html" with gift_certificate=ugs.gift_certificate user_gift_certificate=ugs %} {% endfor %} {% endif %} {% if paid.exists %} diff --git a/project/templates/blocks/popup_enter_gift_code.html b/project/templates/blocks/popup_enter_gift_code.html new file mode 100644 index 00000000..8cbf2b2d --- /dev/null +++ b/project/templates/blocks/popup_enter_gift_code.html @@ -0,0 +1,27 @@ +{% load static %} + diff --git a/project/templates/blocks/popup_gift_certificate.html b/project/templates/blocks/popup_gift_certificate.html index 6416acfa..a9308a2d 100644 --- a/project/templates/blocks/popup_gift_certificate.html +++ b/project/templates/blocks/popup_gift_certificate.html @@ -6,10 +6,12 @@ -