remotes/origin/hotfix/LIL-691
gzbender 7 years ago
parent 176de8f86b
commit 769930e785
  1. 3
      apps/course/templates/course/course.html
  2. 14
      apps/payment/models.py
  3. 18
      apps/payment/views.py
  4. 2
      apps/school/templates/blocks/schedule.html
  5. 2
      apps/school/templates/summer/schedule_purchased.html
  6. 3
      apps/school/views.py
  7. 9
      apps/user/models.py
  8. 2
      apps/user/templates/user/bonus-history.html
  9. 7
      apps/user/views.py
  10. 49
      project/templates/blocks/popup_course_buy.html
  11. 2
      project/templates/blocks/popup_school_buy.html
  12. 5
      project/templates/lilcity/index.html
  13. 1
      project/urls.py
  14. 59
      web/src/js/modules/popup.js
  15. 2
      web/src/sass/_common.sass

@ -34,7 +34,8 @@
{% if user.is_authenticated %} {% if user.is_authenticated %}
{% if not pending %} {% if not pending %}
data-course-buy data-course-buy
href="{% url 'course-checkout' course.id %}" data-popup=".js-popup-course-buy"
href="#"
{% endif %} {% endif %}
{% else %} {% else %}
data-popup=".js-popup-auth" data-popup=".js-popup-auth"

@ -134,9 +134,6 @@ class Payment(PolymorphicModel):
discount = 0 discount = 0
referral_bonus = 0 referral_bonus = 0
referrer_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): if isinstance(payment, CoursePayment):
course = payment.course course = payment.course
user = payment.user user = payment.user
@ -144,6 +141,9 @@ class Payment(PolymorphicModel):
user = payment.user user = payment.user
weekdays = payment.weekdays weekdays = payment.weekdays
date_start = payment.date_start 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(): if payment and payment.is_paid():
price = payment.amount price = payment.amount
elif course: elif course:
@ -226,17 +226,15 @@ class Payment(PolymorphicModel):
] ]
def save(self, *args, **kwargs): 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) amount_data = Payment.calc_amount(payment=self)
if self.status is None and not self.bonus: if self.status is None and not self.bonus:
self.amount = amount_data.get('amount') self.amount = amount_data.get('amount')
if isinstance(self, SchoolPayment): if isinstance(self, SchoolPayment):
self.weekdays = amount_data.get('weekdays') self.weekdays = amount_data.get('weekdays')
super().save(*args, **kwargs) super().save(*args, **kwargs)
if isinstance(self, CoursePayment) and paid: if isinstance(self, CoursePayment) and self.is_paid():
author_balance = getattr(self, 'authorbalance', None) author_balance = getattr(self, 'authorbalance', None)
if not author_balance : if not author_balance:
AuthorBalance.objects.create( AuthorBalance.objects.create(
author=self.course.author, author=self.course.author,
amount=self.amount, amount=self.amount,
@ -246,7 +244,7 @@ class Payment(PolymorphicModel):
author_balance.amount = self.amount author_balance.amount = self.amount
author_balance.save() 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.payment = self
self.user.referral.save() self.user.referral.save()

@ -58,6 +58,7 @@ class CourseBuyView(TemplateView):
template_name = 'payment/paymentwall_widget.html' template_name = 'payment/paymentwall_widget.html'
def get(self, request, pk=None, *args, **kwargs): def get(self, request, pk=None, *args, **kwargs):
use_bonuses = request.GET.get('use_bonuses')
host = urlsplit(self.request.META.get('HTTP_REFERER')) host = urlsplit(self.request.META.get('HTTP_REFERER'))
host = str(host[0]) + '://' + str(host[1]) host = str(host[0]) + '://' + str(host[1])
course = Course.objects.get(id=pk) course = Course.objects.get(id=pk)
@ -70,9 +71,22 @@ class CourseBuyView(TemplateView):
course=course, course=course,
roistat_visit=roistat_visit, 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( product = Product(
f'course_{course_payment.id}', f'course_{course_payment.id}',
course.price, course_payment.amount,
'RUB', 'RUB',
f'Курс "{course.title}"', f'Курс "{course.title}"',
) )
@ -156,7 +170,7 @@ class SchoolBuyView(TemplateView):
school_payment.amount -= request.user.bonus school_payment.amount -= request.user.bonus
school_payment.bonus = bonus school_payment.bonus = bonus
school_payment.save() school_payment.save()
if school_payment.status == Pingback.PINGBACK_TYPE_REGULAR: if school_payment.is_paid():
return redirect(reverse_lazy('payment-success')) return redirect(reverse_lazy('payment-success'))
product = Product( product = Product(
f'school_{school_payment.id}', f'school_{school_payment.id}',

@ -5,7 +5,7 @@
<div class="title title_center">Расписание</div> <div class="title title_center">Расписание</div>
<div class="timing js-timing"> <div class="timing js-timing">
<div class="timing__week"> <div class="timing__week">
{% 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 %} {% include 'blocks/schedule_item.html' with school_schedule=school_schedule live_lesson=school_schedule.current_live_lesson purchased=True %}
{% endfor %} {% endfor %}
</div> </div>

@ -42,7 +42,7 @@
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% else %} {% 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 %} {% include 'blocks/schedule_item.html' with school_schedule=school_schedule live_lesson=school_schedule.current_live_lesson purchased=True %}
{% endfor %} {% endfor %}
{% endif %} {% endif %}

@ -128,7 +128,7 @@ class SchoolView(TemplateView):
school_schedules = SchoolSchedule.objects.all() school_schedules = SchoolSchedule.objects.all()
try: 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: except Exception:
pass pass
school_schedules_dict = {ss.weekday: ss for ss in school_schedules} 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': school_payment_exists,
'is_purchased_future': False, 'is_purchased_future': False,
'min_school_price': SchoolSchedule.objects.aggregate(Min('month_price'))['month_price__min'], 'min_school_price': SchoolSchedule.objects.aggregate(Min('month_price'))['month_price__min'],
'school_schedules_sorted': school_schedules_sorted,
'school_schedules': school_schedules, 'school_schedules': school_schedules,
'school_schedules_purchased': school_schedules_purchased, 'school_schedules_purchased': school_schedules_purchased,
'school_purchased_future': False, 'school_purchased_future': False,

@ -102,10 +102,11 @@ class User(AbstractUser):
@cached_property @cached_property
def balance(self): def balance(self):
from apps.payment.models import Payment
income = self.balances.filter( income = self.balances.filter(
type=0, type=0,
payment__isnull=False, payment__isnull=False,
payment__status__isnull=False payment__status__in=Payment.PW_PAID_STATUSES,
).aggregate( ).aggregate(
models.Sum('amount'), models.Sum('amount'),
models.Sum('commission'), models.Sum('commission'),
@ -120,7 +121,11 @@ class User(AbstractUser):
@cached_property @cached_property
def bonus(self): 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) @receiver(post_save, sender=User)

@ -17,7 +17,7 @@
вы получите {{ config.REFERRER_BONUS }}%, а они {{ config.REFERRAL_BONUS }}% вы получите {{ config.REFERRER_BONUS }}%, а они {{ config.REFERRAL_BONUS }}%
{% endif %} {% endif %}
от суммы их первой покупки на бонусный счет. Приглашайте друзей, накапливайте бонусные баллы, тратьте бонусы от суммы их первой покупки на бонусный счет. Приглашайте друзей, накапливайте бонусные баллы, тратьте бонусы
на приобретения доступа к школе и курсам. Оплата услуг возможна только, если вы накопили баллов на стоимость услуги. на приобретения доступа к школе и курсам.
<br> <br>
Просто отправьте им эту ссылку, по которой они смогут зарегистрироваться: Просто отправьте им эту ссылку, по которой они смогут зарегистрироваться:
</div> </div>

@ -23,7 +23,7 @@ from apps.auth.tokens import verification_email_token
from apps.course.models import Course from apps.course.models import Course
from apps.notification.utils import send_email from apps.notification.utils import send_email
from apps.school.models import SchoolSchedule 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 apps.user.models import AuthorRequest, EmailSubscription, SubscriptionCategory
from .forms import AuthorRequesForm, UserEditForm, WithdrawalForm from .forms import AuthorRequesForm, UserEditForm, WithdrawalForm
@ -300,7 +300,10 @@ class BonusHistoryView(TemplateView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
context = self.get_context_data(**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' % ( context['referrer_url'] = '%s%s?referrer=%s' % (
settings.MAIN_HOST, reverse('index'), short_url.encode_url(request.user.id) settings.MAIN_HOST, reverse('index'), short_url.encode_url(request.user.id)
) )

@ -0,0 +1,49 @@
{% load static %}
<div class="popup js-popup-course-buy">
<div class="popup__wrap js-popup-wrap">
<button class="popup__close js-popup-close">
<svg class="icon icon-close">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-close"></use>
</svg>
</button>
<div class="popup__body">
<div class="buy">
<div class="buy__row">
<div class="buy__col" style="flex: 1;">
<div class="order">
<div class="order__wrap">
<div class="order__title">Ваш заказ:</div>
<div class="order__preview">
<img class="order__pic" src="{% static 'img/order.jpg' %}">
</div>
<div class="order__info">
<div class="order__label">КУРС</div>
<div>{{ course.title }}</div>
{% if request.user.bonuses %}
<label class="buy__bonuses switch" style="display: none;">
<input class="switch__input" type="checkbox" data-bonuses="{{ request.user.bonus }}">
<span class="switch__content">
<span class="switch__cell">Использовать <span class="buy__bonuses-count"></span></span>
</span>
</label>
{% endif %}
</div>
<div class="order__foot">
<div class="order__subtitle">Итого:</div>
<div class="order__total">
<div class="loading-loader"></div>
<span class="order_price_text">{{ course.price }}р.</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="buy__foot">
<a class="buy__btn btn btn_md but_btn_popup" data-link="{% url 'course-checkout' course.id %}" data-price="{{ course.price }}">ПЕРЕЙТИ К ОПЛАТЕ</a>
</div>
</div>
</div>
</div>
</div>

@ -11,7 +11,7 @@
<div class="buy__row"> <div class="buy__row">
<div class="buy__col"> <div class="buy__col">
<div class="buy__head buy__head_main"> <div class="buy__head buy__head_main">
<div class="buy__title">Выбор курса/дня</div> <div class="buy__title">Выбор дня</div>
</div> </div>
</div> </div>
<div class="buy__col"> <div class="buy__col">

@ -146,7 +146,10 @@
</div> </div>
{% include "templates/blocks/footer.html" %} {% include "templates/blocks/footer.html" %}
{% include "templates/blocks/popup_auth.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_course_lock.html" %}
{% include "templates/blocks/popup_subscribe.html" %} {% include "templates/blocks/popup_subscribe.html" %}
</div> </div>

@ -39,6 +39,7 @@ from apps.payment.views import (
from .views import AboutView, IndexView, SchoolSchedulesView from .views import AboutView, IndexView, SchoolSchedulesView
# TODO trim slash in the end
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('auth/', include(('apps.auth.urls', 'lilcity'))), path('auth/', include(('apps.auth.urls', 'lilcity'))),

@ -87,10 +87,47 @@ $(document).ready(function () {
}); });
} }
} }
popup.on('change', '[data-day]', function(){
updateCart();
});
popup.on('change', '[data-bonuses]', function(){
updateCart();
});
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 ? `<del>${coursePrice}</del> ${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') { if( data === '.js-popup-auth') {
let nextUrl = $this.data('auth-next-url'); let nextUrl = $this.data('auth-next-url');
if(nextUrl === 'href') { 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(){ function updateCart(){
var link = $('.but_btn_popup').data('link'); var link = popup.find('.but_btn_popup').data('link');
var $order = $('.order'); var $order = popup.find('.order');
var $orderPrice = $('.order_price_text'); var $orderPrice = popup.find('.order_price_text');
var $orderDates = $('.order__dates'); var $orderDates = popup.find('.order__dates');
var dateStart = popup.data('date-start'); var dateStart = popup.data('date-start');
var days = ['', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье']; var days = ['', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье'];
var weekdays = []; var weekdays = [];
var daysText = []; var daysText = [];
var $bonuses = $('.buy__bonuses'); var $bonuses = popup.find('.buy__bonuses');
var $bonusesCheckbox = $('[data-bonuses]'); var $bonusesCheckbox = popup.find('[data-bonuses]');
var $bonusesCount = $('.buy__bonuses-count'); var $bonusesCount = popup.find('.buy__bonuses-count');
var useBonuses = $bonusesCheckbox.prop('checked'); var useBonuses = $bonusesCheckbox.prop('checked');
var bonuses = +$bonusesCheckbox.data('bonuses'); var bonuses = +$bonusesCheckbox.data('bonuses');
$('[data-day]').each(function() { $('[data-day]').each(function() {

@ -3055,6 +3055,8 @@ a.grey-link
right: 0; right: 0;
padding: 0; padding: 0;
top: 9px; top: 9px;
&__bonuses
margin-top: 10px
.order .order
padding: 2px padding: 2px

Loading…
Cancel
Save