diff --git a/api/v1/serializers/user.py b/api/v1/serializers/user.py
index 3903a66d..a05957db 100644
--- a/api/v1/serializers/user.py
+++ b/api/v1/serializers/user.py
@@ -45,6 +45,7 @@ class UserSerializer(DynamicFieldsMixin, serializers.ModelSerializer):
'balance',
'show_in_mainpage',
'trial_lesson',
+ 'review_url',
)
read_only_fields = (
diff --git a/api/v1/urls.py b/api/v1/urls.py
index 07baaaf1..2ed7195b 100644
--- a/api/v1/urls.py
+++ b/api/v1/urls.py
@@ -18,7 +18,7 @@ from .views import (
UserViewSet, LessonViewSet, ImageObjectViewSet,
SchoolScheduleViewSet, LiveLessonViewSet,
PaymentViewSet, ObjectCommentsViewSet,
- ContestViewSet, ContestWorkViewSet,
+ ContestViewSet, ContestWorkViewSet, NotifiedAboutBonuses,
AuthorBalanceUsersViewSet, CaptureEmail, FAQViewSet, UserGalleryViewSet, BonusesViewSet)
router = DefaultRouter()
@@ -64,6 +64,7 @@ schema_view = get_schema_view(
)
urlpatterns = [
+ path('notified-about-bonuses/', NotifiedAboutBonuses.as_view(), name='notified-about-bonuses'),
path('capture-email/', CaptureEmail.as_view(), name='capture-email'),
path('author-balance-users/', AuthorBalanceUsersViewSet.as_view(), name='author-balance-users'),
path('api-token-auth/', ObtainToken.as_view(), name='api-token-auth'),
diff --git a/api/v1/views.py b/api/v1/views.py
index f43ca18a..47a507ee 100644
--- a/api/v1/views.py
+++ b/api/v1/views.py
@@ -9,9 +9,9 @@ from rest_framework.decorators import (detail_route, list_route, action,
permission_classes, authentication_classes as auth_classes)
from rest_framework.response import Response
from rest_framework.settings import api_settings
+from django.utils.timezone import now
from . import ExtendedModelViewSet, BothListFormatMixin
-
from .serializers.config import ConfigSerializer
from .serializers.course import (
CategorySerializer, LikeSerializer,
@@ -432,6 +432,16 @@ class UserViewSet(ExtendedModelViewSet):
# 'delete': IsAdmin,
# }
+ def update(self, *args, **kwargs):
+ response = super().update(*args, **kwargs)
+ instance = self.get_object()
+
+ if instance.review_url and not instance.bonuses.filter(is_service=True,
+ action_name=UserBonus.ACTION_HAVE_REVIEW).count():
+ UserBonus.objects.create(user=instance, amount=UserBonus.AMOUNT_HAVE_REVIEW, is_service=True,
+ action_name=UserBonus.ACTION_HAVE_REVIEW)
+ return response
+
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
@@ -738,3 +748,16 @@ class BonusesViewSet(BothListFormatMixin, ExtendedModelViewSet):
'referral__referral__first_name',
'referral__referral__last_name',
)
+
+
+class NotifiedAboutBonuses(views.APIView):
+ authentication_classes = ()
+
+ def post(self, request):
+ #FIXME
+ user = User.objects.get(pk=request.data.get('user'))
+ for b in user.bonuses.filter(notified_at__isnull=True):
+ b.notified_at = now()
+ b.save()
+ return Response({'status': 'ok'})
+
diff --git a/apps/payment/migrations/0033_userbonus_notified_at.py b/apps/payment/migrations/0033_userbonus_notified_at.py
new file mode 100644
index 00000000..9804bcb0
--- /dev/null
+++ b/apps/payment/migrations/0033_userbonus_notified_at.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.0.7 on 2019-03-27 20:54
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('payment', '0032_auto_20190207_1233'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='userbonus',
+ name='notified_at',
+ field=models.DateTimeField(blank=True, null=True),
+ ),
+ ]
diff --git a/apps/payment/migrations/0034_auto_20190327_2055.py b/apps/payment/migrations/0034_auto_20190327_2055.py
new file mode 100644
index 00000000..00ec22f5
--- /dev/null
+++ b/apps/payment/migrations/0034_auto_20190327_2055.py
@@ -0,0 +1,22 @@
+# Generated by Django 2.0.7 on 2019-03-27 20:55
+
+from django.utils import timezone
+from django.db import migrations
+
+
+def fill_bonuses_notified_at(apps, schema_editor):
+ UserBonus = apps.get_model('payment', 'UserBonus')
+ for ub in UserBonus.objects.filter(notified_at__isnull=True):
+ ub.notified_at = timezone.now()
+ ub.save()
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('payment', '0033_userbonus_notified_at'),
+ ]
+
+ operations = [
+ migrations.RunPython(fill_bonuses_notified_at),
+ ]
diff --git a/apps/payment/migrations/0035_auto_20190405_1828.py b/apps/payment/migrations/0035_auto_20190405_1828.py
new file mode 100644
index 00000000..55ff4230
--- /dev/null
+++ b/apps/payment/migrations/0035_auto_20190405_1828.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.0.7 on 2019-04-05 18:28
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('payment', '0034_auto_20190327_2055'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='userbonus',
+ name='action_name',
+ field=models.CharField(blank=True, default='', max_length=20),
+ ),
+ ]
diff --git a/apps/payment/models.py b/apps/payment/models.py
index 4e157d4a..a7f0d463 100644
--- a/apps/payment/models.py
+++ b/apps/payment/models.py
@@ -1,4 +1,3 @@
-from decimal import Decimal
import arrow
import short_url
from django.db.models import Func, F
@@ -14,7 +13,6 @@ from django.core.validators import RegexValidator
from django.utils.timezone import now
from django.conf import settings
-from apps.content.models import ImageObject
from project.utils import weekdays_in_date_range
from apps.course.models import Course
@@ -249,6 +247,11 @@ class Payment(PolymorphicModel):
if created:
from apps.notification.tasks import send_gift_certificate
send_gift_certificate(ugs.id)
+ # Если это не первая покупка, - отправляем бонусы юзеру
+ if self.user.paid_one_more and not self.user.bonuses.filter(
+ is_service=True, action_name=UserBonus.ACTION_PAID_ONE_MORE).count():
+ UserBonus.objects.create(user=self.user, amount=UserBonus.AMOUNT_PAID_ONE_MORE, is_service=True,
+ action_name=UserBonus.ACTION_PAID_ONE_MORE)
# Если юзер реферал и нет платежа, где применялась скидка
if hasattr(self.user, 'referral') and not self.user.referral.payment:
# Платеж - как сигнал, что скидка применилась
@@ -299,13 +302,23 @@ class GiftCertificatePayment(Payment):
class UserBonus(models.Model):
+ ACTION_FILL_PROFILE = 'fill_profile'
+ ACTION_PAID_ONE_MORE = 'paid_one_more'
+ ACTION_HAVE_REVIEW = 'have_review'
+ ACTION_CHILD_BIRTHDAY = 'child_birthday'
+ AMOUNT_FILL_PROFILE = 50
+ AMOUNT_PAID_ONE_MORE = 100
+ AMOUNT_HAVE_REVIEW = 300
+ AMOUNT_CHILD_BIRTHDAY = 200
+
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='bonuses')
amount = models.DecimalField(max_digits=8, decimal_places=2, default=0)
payment = models.ForeignKey(Payment, on_delete=models.SET_NULL, null=True)
referral = models.ForeignKey('user.Referral', on_delete=models.SET_NULL, null=True)
created_at = models.DateTimeField(auto_now_add=True)
is_service = models.BooleanField(default=False)
- action_name = models.CharField(max_length=10, blank=True, default='')
+ action_name = models.CharField(max_length=20, blank=True, default='')
+ notified_at = models.DateTimeField(blank=True, null=True)
class Meta:
ordering = ('created_at',)
diff --git a/apps/payment/tests/__init__.py b/apps/payment/tests/__init__.py
new file mode 100644
index 00000000..40a96afc
--- /dev/null
+++ b/apps/payment/tests/__init__.py
@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-
diff --git a/apps/payment/tests.py b/apps/payment/tests/tests_models.py
similarity index 100%
rename from apps/payment/tests.py
rename to apps/payment/tests/tests_models.py
diff --git a/apps/user/migrations/0031_user_review_url.py b/apps/user/migrations/0031_user_review_url.py
new file mode 100644
index 00000000..abac92e9
--- /dev/null
+++ b/apps/user/migrations/0031_user_review_url.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.0.7 on 2019-04-04 18:07
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('user', '0030_auto_20190318_1320'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='user',
+ name='review_url',
+ field=models.URLField(blank=True, default='', verbose_name='Ссылка на видеоотзыв'),
+ ),
+ ]
diff --git a/apps/user/models.py b/apps/user/models.py
index 87d43490..aca57b23 100644
--- a/apps/user/models.py
+++ b/apps/user/models.py
@@ -94,6 +94,7 @@ class User(AbstractUser):
child_gender = models.CharField(
'Пол ребенка', max_length=1, default='n', choices=GENDER_CHOICES)
child_birthday = models.DateField('День рождения ребенка', null=True, blank=True)
+ review_url = models.URLField('Ссылка на видеоотзыв', blank=True, default='')
objects = UserManager()
@@ -138,6 +139,22 @@ class User(AbstractUser):
Q(payment__isnull=False, payment__status__in=Payment.PW_PAID_STATUSES) | Q(is_service=True),
).aggregate(models.Sum('amount')).get('amount__sum') or 0)
+ @property
+ def has_new_bonuses(self):
+ from apps.payment.models import Payment
+ last_bonus = self.bonuses.filter(
+ Q(payment__isnull=False, payment__status__in=Payment.PW_PAID_STATUSES) | Q(is_service=True),
+ ).order_by('-created_at').first()
+ return bool(last_bonus) and not last_bonus.notified_at
+
+ @property
+ def paid_one_more(self):
+ from apps.payment.models import SchoolPayment, CoursePayment, Payment
+ school_payments_cnt = SchoolPayment.objects.filter(status__in=Payment.PW_PAID_STATUSES, user=self,
+ add_days=False).count()
+ course_payment_cnt = CoursePayment.objects.filter(status__in=Payment.PW_PAID_STATUSES, user=self).count()
+ return school_payments_cnt > 1 or course_payment_cnt > 1 or (school_payments_cnt and course_payment_cnt)
+
@receiver(post_save, sender=User)
def create_auth_token(sender, instance=None, created=False, **kwargs):
diff --git a/apps/user/templates/user/bonus-history.html b/apps/user/templates/user/bonus-history.html
index ef3bf9d8..211bf9f5 100644
--- a/apps/user/templates/user/bonus-history.html
+++ b/apps/user/templates/user/bonus-history.html
@@ -3,7 +3,6 @@
{% load rupluralize from plural %}
{% block content %}
-
@@ -12,24 +11,82 @@
1 LIL = 1 ₽
-
- Приглашайте друзей в Lil School и получайте {{ config.REFERRER_BONUS }}%
- от суммы их первой покупки. Накапливайте монеты и тратьте их на оплату школы и курсов.
-
- Просто отправьте эту ссылку, по которой ваши друзья могут присоединиться к нам:
+
+
+
Приглашайте друзей в Lil School
+
+ Получайте {{ config.REFERRER_BONUS }}% от суммы их первой покупки.
+
+ Просто отправьте эту ссылку, по которой ваши друзья могут присоединиться к нам:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
Как еще заработать лилики?
+
+ Накапливайте монеты и тратьте их на оплату школы и курсов. Около трети наших учеников обучаются за счет лиликов.
+
+
+
+
+
1
+
+
Заполнить профиль
+ Заполните свой профиль, включая номер телефона.
+
{% if request.user.child_first_name and request.user.child_last_name and request.user.child_birthday %}
+ {% endif %}
- {% include 'templates/blocks/share.html' with share_object_name="ссылкой" share_url=referrer_url share_tw_title=share_text share_tg_text=share_text %}
Приглашайте друзей в Lil School и получайте {{ config.REFERRER_BONUS }}% от суммы их первой покупки.
+ Накапливайте монеты и тратьте их на оплату школы и курсов.