From b3c499481cdee482bc75d7c7c5f393acecd673cf Mon Sep 17 00:00:00 2001 From: gzbender Date: Tue, 4 Sep 2018 03:35:49 +0500 Subject: [PATCH] lil-583 --- api/v1/serializers/config.py | 8 +- api/v1/views.py | 2 +- apps/auth/views.py | 8 +- apps/config/models.py | 4 +- apps/payment/migrations/0020_userbonus.py | 28 ------- apps/payment/models.py | 77 ++++++++----------- apps/user/migrations/0023_referral.py | 29 ------- apps/user/migrations/0024_referral_payment.py | 20 ----- .../migrations/0025_auto_20180820_0651.py | 20 ----- apps/user/models.py | 8 +- apps/user/templates/user/bonus-history.html | 6 +- apps/user/views.py | 7 +- project/templates/blocks/lil_store_js.html | 4 +- project/views.py | 2 +- web/src/js/modules/api.js | 2 +- web/src/js/modules/common.js | 4 +- web/src/js/modules/popup.js | 2 +- 17 files changed, 65 insertions(+), 166 deletions(-) delete mode 100644 apps/payment/migrations/0020_userbonus.py delete mode 100644 apps/user/migrations/0023_referral.py delete mode 100644 apps/user/migrations/0024_referral_payment.py delete mode 100644 apps/user/migrations/0025_auto_20180820_0651.py diff --git a/api/v1/serializers/config.py b/api/v1/serializers/config.py index 46cb40b2..e494f861 100644 --- a/api/v1/serializers/config.py +++ b/api/v1/serializers/config.py @@ -20,8 +20,8 @@ class ConfigSerializer(serializers.ModelSerializer): MAIN_PAGE_TOP_IMAGE = serializers.SerializerMethodField() # SCHOOL_LOGO_IMAGE = serializers.ImageField(required=False, allow_null=True) # MAIN_PAGE_TOP_IMAGE = serializers.ImageField(required=False, allow_null=True) - REFERRER_CASHBACK = serializers.IntegerField() - REFERRAL_DISCOUNT = serializers.IntegerField() + REFERRER_BONUS = serializers.IntegerField() + REFERRAL_BONUS = serializers.IntegerField() class Meta: model = Config @@ -39,8 +39,8 @@ class ConfigSerializer(serializers.ModelSerializer): 'INSTAGRAM_PROFILE_URL', 'SCHOOL_LOGO_IMAGE', 'MAIN_PAGE_TOP_IMAGE', - 'REFERRER_CASHBACK', - 'REFERRAL_DISCOUNT', + 'REFERRER_BONUS', + 'REFERRAL_BONUS', ) def get_SCHOOL_LOGO_IMAGE(self, config): diff --git a/api/v1/views.py b/api/v1/views.py index ca551de4..7620244b 100644 --- a/api/v1/views.py +++ b/api/v1/views.py @@ -476,7 +476,7 @@ class PaymentViewSet(ExtendedModelViewSet): return queryset.filter(status__isnull=False).order_by('-created_at') - @action(methods=['get'], detail=False, url_path='calc-amount') + @action(methods=['get'], detail=False, url_path='calc-amount', authentication_classes=[], permission_classes=[]) def calc_amount(self, request, pk=None): user = request.query_params.get('user') course = request.query_params.get('course') diff --git a/apps/auth/views.py b/apps/auth/views.py index f83a9269..c9ae8dfc 100644 --- a/apps/auth/views.py +++ b/apps/auth/views.py @@ -56,8 +56,8 @@ class LearnerRegistrationView(FormView): user.save() referrer = self.request.session.get('referrer') if referrer: - Referral.objects.create(referral=user, referrer_id=referrer, discount=config.REFERRAL_DISCOUNT, - referrer_cashback=config.REFERRER_CASHBACK) + Referral.objects.create(referral=user, referrer_id=referrer, bonus=config.REFERRAL_BONUS, + referrer_bonus=config.REFERRER_BONUS) # TODO: email admins? мб реферера уже нет, старая ссылка self.request.session['referrer'] = None login(self.request, user) @@ -198,8 +198,8 @@ class FacebookLoginOrRegistration(View): referrer = self.request.session.get('referrer') if referrer: config = Config.load() - Referral.objects.create(referral=user, referrer_id=referrer, discount=config.REFERRAL_DISCOUNT, - referrer_cashback=config.REFERRER_CASHBACK) + Referral.objects.create(referral=user, referrer_id=referrer, bonus=config.REFERRAL_BONUS, + referrer_bonus=config.REFERRER_BONUS) # TODO: email admins? мб реферера уже нет, старая ссылка self.request.session['referrer'] = None diff --git a/apps/config/models.py b/apps/config/models.py index 7e7e833a..498dd00f 100644 --- a/apps/config/models.py +++ b/apps/config/models.py @@ -47,7 +47,7 @@ class Config(models.Model): 'SERVICE_DISCOUNT': '', 'SCHOOL_LOGO_IMAGE': '', 'MAIN_PAGE_TOP_IMAGE': '', - 'REFERRER_CASHBACK': '', - 'REFERRAL_DISCOUNT': '', + 'REFERRER_BONUS': '', + 'REFERRAL_BONUS': '', } return obj diff --git a/apps/payment/migrations/0020_userbonus.py b/apps/payment/migrations/0020_userbonus.py deleted file mode 100644 index 4b029f87..00000000 --- a/apps/payment/migrations/0020_userbonus.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 2.0.6 on 2018-08-20 06:51 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('user', '0025_auto_20180820_0651'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('payment', '0019_payment_roistat_visit'), - ] - - operations = [ - migrations.CreateModel( - name='UserBonus', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('amount', models.DecimalField(decimal_places=2, default=0, editable=False, max_digits=8)), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('payment', models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='payment.Payment')), - ('referral', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='user.Referral')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='bonuses', to=settings.AUTH_USER_MODEL)), - ], - ), - ] diff --git a/apps/payment/models.py b/apps/payment/models.py index 016646a7..81acf8e7 100644 --- a/apps/payment/models.py +++ b/apps/payment/models.py @@ -110,17 +110,17 @@ class Payment(PolymorphicModel): ordering = ('created_at',) @classmethod - def calc_amount(cls, course_payment=None, school_payment=None, user=None, course=None, weekdays=None, + def calc_amount(cls, payment=None, user=None, course=None, weekdays=None, add_days=False, date_start=None, date_end=None): - if course_payment: - course = course_payment.course - user = course_payment.user - if school_payment: - user = school_payment.user - weekdays = school_payment.weekdays - add_days = school_payment.add_days - date_start = school_payment.date_start - date_end = school_payment.date_end + if isinstance(payment, CoursePayment): + course = payment.course + user = payment.user + if isinstance(payment, SchoolPayment): + user = payment.user + weekdays = payment.weekdays + add_days = payment.add_days + date_start = payment.date_start + date_end = payment.date_end referral_bonus = 0 referrer_bonus = 0 if hasattr(user, 'referral') and not user.referral.payment: @@ -184,30 +184,25 @@ class Payment(PolymorphicModel): Pingback.PINGBACK_TYPE_RISK_REVIEWED_DECLINED, ] - -class CoursePayment(Payment): - course = models.ForeignKey(Course, on_delete=models.CASCADE, verbose_name='Курс', related_name='payments') - - class Meta: - verbose_name = 'Платеж за курс' - verbose_name_plural = 'Платежи за курсы' - def save(self, *args, **kwargs): - amount_data = Payment.calc_amount(course_payment=self) + amount_data = Payment.calc_amount(payment=self) self.amount = amount_data.get('amount') super().save(*args, **kwargs) - author_balance = getattr(self, 'authorbalance', None) - if not author_balance: - AuthorBalance.objects.create( - author=self.course.author, - amount=self.amount, - payment=self, - ) - else: - author_balance.amount = self.amount - author_balance.save() + if isinstance(self, CoursePayment): + author_balance = getattr(self, 'authorbalance', None) + if not author_balance: + AuthorBalance.objects.create( + author=self.course.author, + amount=self.amount, + payment=self, + ) + else: + author_balance.amount = self.amount + author_balance.save() # Если юзер реферал и нет платежа, где применялась скидка - if hasattr(self.user, 'referral') and not self.user.referral.payment: + if hasattr(self.user, 'referral') and not self.user.referral.payment\ + and self.status in [Pingback.PINGBACK_TYPE_REGULAR, Pingback.PINGBACK_TYPE_GOODWILL, + Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,]: # Платеж - как сигнал, что скидка применилась self.user.referral.payment = self self.user.referral.save() @@ -215,6 +210,14 @@ class CoursePayment(Payment): self.user.referral.send_bonuses(amount_data.get('referral_bonus'), amount_data.get('referrer_bonus')) +class CoursePayment(Payment): + course = models.ForeignKey(Course, on_delete=models.CASCADE, verbose_name='Курс', related_name='payments') + + class Meta: + verbose_name = 'Платеж за курс' + verbose_name_plural = 'Платежи за курсы' + + class SchoolPayment(Payment): weekdays = ArrayField(models.IntegerField(), size=7, verbose_name='Дни недели') add_days = models.BooleanField('Докупленные дни', default=False) @@ -232,18 +235,6 @@ class SchoolPayment(Payment): ]) return days - def save(self, *args, **kwargs): - amount_data = Payment.calc_amount(school_payment=self) - self.amount = amount_data.get('amount') - super().save(*args, **kwargs) - # Если юзер реферал и нет платежа, где применялась скидка - if not self.add_days and hasattr(self.user, 'referral') and not self.user.referral.payment: - # Платеж - как сигнал, что скидка применилась - self.user.referral.payment = self - self.user.referral.save() - # Отправляем кэшбэк - self.user.referral.send_bonuses(amount_data.get('referral_bonus'), amount_data.get('referrer_bonus')) - @property def date_end_humanize(self): return arrow.get(self.date_end, settings.TIME_ZONE).humanize(locale='ru') @@ -252,7 +243,7 @@ class SchoolPayment(Payment): class UserBonus(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='bonuses') amount = models.DecimalField(max_digits=8, decimal_places=2, default=0, editable=False) - payment = models.OneToOneField(Payment, on_delete=models.SET_NULL, null=True) + 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) diff --git a/apps/user/migrations/0023_referral.py b/apps/user/migrations/0023_referral.py deleted file mode 100644 index 2edf4621..00000000 --- a/apps/user/migrations/0023_referral.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 2.0.6 on 2018-07-29 05:24 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('user', '0022_user_instagram_hashtag'), - ] - - operations = [ - migrations.CreateModel( - name='Referral', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('discount', models.IntegerField()), - ('referrer_cashback', models.IntegerField()), - ('referral', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ('referrer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='referrals', to=settings.AUTH_USER_MODEL)), - ], - options={ - 'verbose_name': 'Реферал', - 'verbose_name_plural': 'Рефералы', - }, - ), - ] diff --git a/apps/user/migrations/0024_referral_payment.py b/apps/user/migrations/0024_referral_payment.py deleted file mode 100644 index f68f7632..00000000 --- a/apps/user/migrations/0024_referral_payment.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 2.0.6 on 2018-07-30 18:24 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('payment', '0019_payment_roistat_visit'), - ('user', '0023_referral'), - ] - - operations = [ - migrations.AddField( - model_name='referral', - name='payment', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='payment.Payment'), - ), - ] diff --git a/apps/user/migrations/0025_auto_20180820_0651.py b/apps/user/migrations/0025_auto_20180820_0651.py deleted file mode 100644 index ad53086e..00000000 --- a/apps/user/migrations/0025_auto_20180820_0651.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 2.0.6 on 2018-08-20 06:51 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('user', '0024_referral_payment'), - ] - - operations = [ - migrations.AlterField( - model_name='referral', - name='referral', - field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='referral', to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/apps/user/models.py b/apps/user/models.py index c2fcf3cd..887167ad 100644 --- a/apps/user/models.py +++ b/apps/user/models.py @@ -1,4 +1,6 @@ from json import dumps + +from django.utils.functional import cached_property from rest_framework.authtoken.models import Token from phonenumber_field.modelfields import PhoneNumberField @@ -89,7 +91,7 @@ class User(AbstractUser): user_data = dumps(user_data, ensure_ascii=False) return user_data - @property + @cached_property def balance(self): aggregate = self.balances.filter( type=0, @@ -103,9 +105,9 @@ class User(AbstractUser): commission = aggregate.get('commission__sum') or 0 return amount - commission - @property + @cached_property def bonus(self): - return self.balances.aggregate(models.Sum('amount')).get('amount__sum') or 0 + return int(self.bonuses.aggregate(models.Sum('amount')).get('amount__sum')) or 0 @receiver(post_save, sender=User) diff --git a/apps/user/templates/user/bonus-history.html b/apps/user/templates/user/bonus-history.html index 72be8b05..43e45fbd 100644 --- a/apps/user/templates/user/bonus-history.html +++ b/apps/user/templates/user/bonus-history.html @@ -40,12 +40,12 @@ {% if payment.balance %}
{{payment.balance.amount}}
{% else %} -
{{payment.amount}}
+
{{payment.amount|floatformat }}
{% endif %} {% if bonus.referral %} -
{{ bonus.referral.get_full_name }}
+
{{ bonus.referral.referral.get_full_name }}
{% endif %} -
{{ bonus.amount }}
+
{{ bonus.amount|floatformat }}
{% endwith %} {% empty %} diff --git a/apps/user/views.py b/apps/user/views.py index df52c724..7ff653b5 100644 --- a/apps/user/views.py +++ b/apps/user/views.py @@ -5,6 +5,7 @@ from os.path import splitext from datetime import timedelta from paymentwall import Pingback import short_url +from urllib.parse import urljoin from django.conf import settings from django.contrib.auth import login @@ -313,7 +314,7 @@ class BonusHistoryView(TemplateView): def get(self, request, *args, **kwargs): context = self.get_context_data(**kwargs) context['bonuses'] = request.user.bonuses.all() - context['referrer_url'] = '%s%s?referrer=%s' % ( - settings.MAIN_HOST, reverse('index'), short_url.encode_url(request.user.id) - ) + context['referrer_url'] = urljoin(settings.MAIN_HOST, '%s?referrer=%s' % ( + reverse('index'), short_url.encode_url(request.user.id) + )) return self.render_to_response(context) diff --git a/project/templates/blocks/lil_store_js.html b/project/templates/blocks/lil_store_js.html index ac729e61..04f69e59 100644 --- a/project/templates/blocks/lil_store_js.html +++ b/project/templates/blocks/lil_store_js.html @@ -1,12 +1,14 @@ {% load static %} diff --git a/project/views.py b/project/views.py index abf81bcc..bc00f173 100644 --- a/project/views.py +++ b/project/views.py @@ -82,7 +82,7 @@ class IndexView(TemplateView): referrer = None context.update({ - 'is_registration': bool(referrer), + 'is_referral_registration': bool(referrer), 'online': online, 'online_coming_soon': online_coming_soon, 'school_schedule': school_schedule, diff --git a/web/src/js/modules/api.js b/web/src/js/modules/api.js index d27c2f8a..63c8412a 100644 --- a/web/src/js/modules/api.js +++ b/web/src/js/modules/api.js @@ -506,7 +506,7 @@ export const api = { return api.get('/api/v1/payments/calc-amount', { params: params, headers: { - 'Authorization': `Token ${window.STORE.accessToken}`, + 'Authorization': `Token ${window.LIL_STORE.accessToken}`, } }); } diff --git a/web/src/js/modules/common.js b/web/src/js/modules/common.js index d4b6b4b8..af1601ec 100644 --- a/web/src/js/modules/common.js +++ b/web/src/js/modules/common.js @@ -41,7 +41,7 @@ $(document).ready(function () { }) }); - if(window.LIL_STORE.isRegistration && ! window.LIL_STORE.user.id){ + if(window.LIL_STORE.flags.isReferralRegistration && ! window.LIL_STORE.user.id){ $('.js-header-enter').click(); } }); @@ -71,4 +71,4 @@ function updateHeader() { headerElement.css('top', ''); } } -} \ No newline at end of file +} diff --git a/web/src/js/modules/popup.js b/web/src/js/modules/popup.js index 73335575..25295f7b 100644 --- a/web/src/js/modules/popup.js +++ b/web/src/js/modules/popup.js @@ -158,7 +158,7 @@ $(document).ready(function () { }); if(weekdays.length){ - api.getPaymentAmount({ user: window.STORE.user.id, weekdays: weekdays }) + api.getPaymentAmount({ user: window.LIL_STORE.user.id, weekdays: weekdays }) .then((response) => { var text = ''; if(response.data.price != response.data.amount) {