diff --git a/apps/course/templates/course/course.html b/apps/course/templates/course/course.html
index 5b651689..20266fe1 100644
--- a/apps/course/templates/course/course.html
+++ b/apps/course/templates/course/course.html
@@ -34,7 +34,8 @@
{% if user.is_authenticated %}
{% if not pending %}
data-course-buy
- href="{% url 'course-checkout' course.id %}"
+ data-popup=".js-popup-course-buy"
+ href="#"
{% endif %}
{% else %}
data-popup=".js-popup-auth"
diff --git a/apps/payment/models.py b/apps/payment/models.py
index 90478c98..0d406323 100644
--- a/apps/payment/models.py
+++ b/apps/payment/models.py
@@ -134,9 +134,6 @@ class Payment(PolymorphicModel):
discount = 0
referral_bonus = 0
referrer_bonus = 0
- if hasattr(user, 'referral') and not user.referral.payment:
- referral_bonus = user.referral.bonus
- referrer_bonus = user.referral.referrer_bonus
if isinstance(payment, CoursePayment):
course = payment.course
user = payment.user
@@ -144,6 +141,9 @@ class Payment(PolymorphicModel):
user = payment.user
weekdays = payment.weekdays
date_start = payment.date_start
+ if hasattr(user, 'referral') and not user.referral.payment:
+ referral_bonus = user.referral.bonus
+ referrer_bonus = user.referral.referrer_bonus
if payment and payment.is_paid():
price = payment.amount
elif course:
@@ -226,17 +226,15 @@ class Payment(PolymorphicModel):
]
def save(self, *args, **kwargs):
- paid = self.status in [Pingback.PINGBACK_TYPE_REGULAR, Pingback.PINGBACK_TYPE_GOODWILL,
- Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,]
amount_data = Payment.calc_amount(payment=self)
if self.status is None and not self.bonus:
self.amount = amount_data.get('amount')
if isinstance(self, SchoolPayment):
self.weekdays = amount_data.get('weekdays')
super().save(*args, **kwargs)
- if isinstance(self, CoursePayment) and paid:
+ if isinstance(self, CoursePayment) and self.is_paid():
author_balance = getattr(self, 'authorbalance', None)
- if not author_balance :
+ if not author_balance:
AuthorBalance.objects.create(
author=self.course.author,
amount=self.amount,
@@ -246,7 +244,7 @@ class Payment(PolymorphicModel):
author_balance.amount = self.amount
author_balance.save()
# Если юзер реферал и нет платежа, где применялась скидка
- if hasattr(self.user, 'referral') and not self.user.referral.payment and paid:
+ if hasattr(self.user, 'referral') and not self.user.referral.payment and self.is_paid():
# Платеж - как сигнал, что скидка применилась
self.user.referral.payment = self
self.user.referral.save()
diff --git a/apps/payment/views.py b/apps/payment/views.py
index 5663df39..6be7734f 100644
--- a/apps/payment/views.py
+++ b/apps/payment/views.py
@@ -58,6 +58,7 @@ class CourseBuyView(TemplateView):
template_name = 'payment/paymentwall_widget.html'
def get(self, request, pk=None, *args, **kwargs):
+ use_bonuses = request.GET.get('use_bonuses')
host = urlsplit(self.request.META.get('HTTP_REFERER'))
host = str(host[0]) + '://' + str(host[1])
course = Course.objects.get(id=pk)
@@ -70,9 +71,22 @@ class CourseBuyView(TemplateView):
course=course,
roistat_visit=roistat_visit,
)
+ if use_bonuses:
+ if request.user.bonus >= course_payment.amount:
+ bonus = UserBonus.objects.create(amount= -course_payment.amount, user=request.user, payment=course_payment)
+ course_payment.amount = 0
+ course_payment.status = Pingback.PINGBACK_TYPE_REGULAR
+ else:
+ bonus = UserBonus.objects.create(amount= -request.user.bonus, user=request.user,
+ payment=course_payment)
+ course_payment.amount -= request.user.bonus
+ course_payment.bonus = bonus
+ course_payment.save()
+ if course_payment.is_paid():
+ return redirect(reverse_lazy('course_payment_success', args=[course.id]))
product = Product(
f'course_{course_payment.id}',
- course.price,
+ course_payment.amount,
'RUB',
f'Курс "{course.title}"',
)
@@ -156,7 +170,7 @@ class SchoolBuyView(TemplateView):
school_payment.amount -= request.user.bonus
school_payment.bonus = bonus
school_payment.save()
- if school_payment.status == Pingback.PINGBACK_TYPE_REGULAR:
+ if school_payment.is_paid():
return redirect(reverse_lazy('payment-success'))
product = Product(
f'school_{school_payment.id}',
diff --git a/apps/school/templates/blocks/schedule.html b/apps/school/templates/blocks/schedule.html
index ab97055f..15b129fb 100644
--- a/apps/school/templates/blocks/schedule.html
+++ b/apps/school/templates/blocks/schedule.html
@@ -5,7 +5,7 @@
Расписание
- {% for school_schedule in school_schedules %}
+ {% for school_schedule in school_schedules_sorted %}
{% include 'blocks/schedule_item.html' with school_schedule=school_schedule live_lesson=school_schedule.current_live_lesson purchased=True %}
{% endfor %}
diff --git a/apps/school/templates/summer/schedule_purchased.html b/apps/school/templates/summer/schedule_purchased.html
index a2106299..3f722678 100644
--- a/apps/school/templates/summer/schedule_purchased.html
+++ b/apps/school/templates/summer/schedule_purchased.html
@@ -42,7 +42,7 @@
{% endif %}
{% endfor %}
{% else %}
- {% for school_schedule in school_schedules %}
+ {% for school_schedule in school_schedules_sorted %}
{% include 'blocks/schedule_item.html' with school_schedule=school_schedule live_lesson=school_schedule.current_live_lesson purchased=True %}
{% endfor %}
{% endif %}
diff --git a/apps/school/views.py b/apps/school/views.py
index bdb3a848..5729f04c 100644
--- a/apps/school/views.py
+++ b/apps/school/views.py
@@ -128,7 +128,7 @@ class SchoolView(TemplateView):
school_schedules = SchoolSchedule.objects.all()
try:
- school_schedules = sorted(school_schedules, key=lambda ss: ss.current_live_lesson and ss.current_live_lesson.date)
+ school_schedules_sorted = sorted(school_schedules, key=lambda ss: ss.current_live_lesson and ss.current_live_lesson.date)
except Exception:
pass
school_schedules_dict = {ss.weekday: ss for ss in school_schedules}
@@ -190,6 +190,7 @@ class SchoolView(TemplateView):
'is_purchased': school_payment_exists,
'is_purchased_future': False,
'min_school_price': SchoolSchedule.objects.aggregate(Min('month_price'))['month_price__min'],
+ 'school_schedules_sorted': school_schedules_sorted,
'school_schedules': school_schedules,
'school_schedules_purchased': school_schedules_purchased,
'school_purchased_future': False,
diff --git a/apps/user/models.py b/apps/user/models.py
index 84d9a329..3f41a016 100644
--- a/apps/user/models.py
+++ b/apps/user/models.py
@@ -102,10 +102,11 @@ class User(AbstractUser):
@cached_property
def balance(self):
+ from apps.payment.models import Payment
income = self.balances.filter(
type=0,
payment__isnull=False,
- payment__status__isnull=False
+ payment__status__in=Payment.PW_PAID_STATUSES,
).aggregate(
models.Sum('amount'),
models.Sum('commission'),
@@ -120,7 +121,11 @@ class User(AbstractUser):
@cached_property
def bonus(self):
- return int(self.bonuses.aggregate(models.Sum('amount')).get('amount__sum') or 0)
+ from apps.payment.models import Payment
+ return int(self.bonuses.filter(
+ payment__isnull=False,
+ payment__status__in=Payment.PW_PAID_STATUSES,
+ ).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 d4f32bcb..cfddee9d 100644
--- a/apps/user/templates/user/bonus-history.html
+++ b/apps/user/templates/user/bonus-history.html
@@ -17,7 +17,7 @@
вы получите {{ config.REFERRER_BONUS }}%, а они {{ config.REFERRAL_BONUS }}%
{% endif %}
от суммы их первой покупки на бонусный счет. Приглашайте друзей, накапливайте бонусные баллы, тратьте бонусы
- на приобретения доступа к школе и курсам. Оплата услуг возможна только, если вы накопили баллов на стоимость услуги.
+ на приобретения доступа к школе и курсам.
Просто отправьте им эту ссылку, по которой они смогут зарегистрироваться:
diff --git a/apps/user/views.py b/apps/user/views.py
index 6f54861d..3b18c952 100644
--- a/apps/user/views.py
+++ b/apps/user/views.py
@@ -23,7 +23,7 @@ from apps.auth.tokens import verification_email_token
from apps.course.models import Course
from apps.notification.utils import send_email
from apps.school.models import SchoolSchedule
-from apps.payment.models import AuthorBalance, CoursePayment, SchoolPayment
+from apps.payment.models import AuthorBalance, CoursePayment, SchoolPayment, Payment
from apps.user.models import AuthorRequest, EmailSubscription, SubscriptionCategory
from .forms import AuthorRequesForm, UserEditForm, WithdrawalForm
@@ -300,7 +300,10 @@ class BonusHistoryView(TemplateView):
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
- context['bonuses'] = request.user.bonuses.all()
+ context['bonuses'] = request.user.bonuses.filter(
+ payment__isnull=False,
+ payment__status__in=Payment.PW_PAID_STATUSES,
+ )
context['referrer_url'] = '%s%s?referrer=%s' % (
settings.MAIN_HOST, reverse('index'), short_url.encode_url(request.user.id)
)
diff --git a/project/templates/blocks/popup_course_buy.html b/project/templates/blocks/popup_course_buy.html
new file mode 100644
index 00000000..1ce320ca
--- /dev/null
+++ b/project/templates/blocks/popup_course_buy.html
@@ -0,0 +1,49 @@
+{% load static %}
+
+
diff --git a/project/templates/blocks/popup_buy.html b/project/templates/blocks/popup_school_buy.html
similarity index 98%
rename from project/templates/blocks/popup_buy.html
rename to project/templates/blocks/popup_school_buy.html
index 093b19ac..7178b415 100644
--- a/project/templates/blocks/popup_buy.html
+++ b/project/templates/blocks/popup_school_buy.html
@@ -11,7 +11,7 @@
-
Выбор курса/дня
+
Выбор дня
diff --git a/project/templates/lilcity/index.html b/project/templates/lilcity/index.html
index 7b8204a0..fbf876b3 100644
--- a/project/templates/lilcity/index.html
+++ b/project/templates/lilcity/index.html
@@ -146,7 +146,10 @@
{% include "templates/blocks/footer.html" %}
{% include "templates/blocks/popup_auth.html" %}
- {% include "templates/blocks/popup_buy.html" %}
+ {% include "templates/blocks/popup_school_buy.html" %}
+ {% if course %}
+ {% include "templates/blocks/popup_course_buy.html" %}
+ {% endif %}
{% include "templates/blocks/popup_course_lock.html" %}
{% include "templates/blocks/popup_subscribe.html" %}
diff --git a/project/urls.py b/project/urls.py
index cf0a3c0c..38773131 100644
--- a/project/urls.py
+++ b/project/urls.py
@@ -39,6 +39,7 @@ from apps.payment.views import (
from .views import AboutView, IndexView, SchoolSchedulesView
+# TODO trim slash in the end
urlpatterns = [
path('admin/', admin.site.urls),
path('auth/', include(('apps.auth.urls', 'lilcity'))),
diff --git a/web/src/js/modules/popup.js b/web/src/js/modules/popup.js
index adfa7510..b7fe9789 100644
--- a/web/src/js/modules/popup.js
+++ b/web/src/js/modules/popup.js
@@ -87,10 +87,47 @@ $(document).ready(function () {
});
}
}
+ popup.on('change', '[data-day]', function(){
+ updateCart();
+ });
+
+ popup.on('change', '[data-bonuses]', function(){
+ updateCart();
+ });
updateCart();
}
+ if(data === '.js-popup-course-buy'){
+ const updateCourseCart = () => {
+ var $orderPrice = popup.find('.order_price_text');
+ var useBonuses = $bonusesCheckbox.prop('checked');
+ var amount = useBonuses ? coursePrice - bonusesCount : coursePrice;
+
+ $orderPrice.html(amount !== coursePrice ? `${coursePrice} ${amount}р.` : `${amount}р.`);
+ $buyBtn.attr('href', link + '?' + decodeURIComponent($.param({
+ use_bonuses: useBonuses || ''
+ })));
+ }
+ var $buyBtn = popup.find('.but_btn_popup');
+ var link = $buyBtn.data('link');
+ var coursePrice = +$buyBtn.data('price').replace(',', '.');
+ var $bonuses = popup.find('.buy__bonuses');
+ var $bonusesCount = popup.find('.buy__bonuses-count');
+ var $bonusesCheckbox = popup.find('[data-bonuses]');
+ var bonuses = +$bonusesCheckbox.data('bonuses');
+ var bonusesCount = bonuses > coursePrice ? coursePrice : bonuses;
+
+ $bonuses.hide();
+ if(bonuses){
+ $bonusesCount.text(rupluralize(bonusesCount, ['бонус', 'бонуса', 'бонусов']));
+ $bonuses.show();
+ }
+
+ popup.on('change', '[data-bonuses]', updateCourseCart);
+ updateCourseCart();
+ }
+
if( data === '.js-popup-auth') {
let nextUrl = $this.data('auth-next-url');
if(nextUrl === 'href') {
@@ -146,26 +183,18 @@ $(document).ready(function () {
});
}
- $(document).on('change', '[data-day]', function(){
- updateCart();
- });
-
- $(document).on('change', '[data-bonuses]', function(){
- updateCart();
- });
-
function updateCart(){
- var link = $('.but_btn_popup').data('link');
- var $order = $('.order');
- var $orderPrice = $('.order_price_text');
- var $orderDates = $('.order__dates');
+ var link = popup.find('.but_btn_popup').data('link');
+ var $order = popup.find('.order');
+ var $orderPrice = popup.find('.order_price_text');
+ var $orderDates = popup.find('.order__dates');
var dateStart = popup.data('date-start');
var days = ['', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье'];
var weekdays = [];
var daysText = [];
- var $bonuses = $('.buy__bonuses');
- var $bonusesCheckbox = $('[data-bonuses]');
- var $bonusesCount = $('.buy__bonuses-count');
+ var $bonuses = popup.find('.buy__bonuses');
+ var $bonusesCheckbox = popup.find('[data-bonuses]');
+ var $bonusesCount = popup.find('.buy__bonuses-count');
var useBonuses = $bonusesCheckbox.prop('checked');
var bonuses = +$bonusesCheckbox.data('bonuses');
$('[data-day]').each(function() {
diff --git a/web/src/sass/_common.sass b/web/src/sass/_common.sass
index afe6fd2c..a585dbb8 100755
--- a/web/src/sass/_common.sass
+++ b/web/src/sass/_common.sass
@@ -3055,6 +3055,8 @@ a.grey-link
right: 0;
padding: 0;
top: 9px;
+ &__bonuses
+ margin-top: 10px
.order
padding: 2px