LIL-650 Исправление логики add_days

remotes/origin/hotfix/LIL-661
gzbender 7 years ago
parent d77d16a87d
commit 34bc8507c9
  1. 13
      api/v1/views.py
  2. 86
      apps/payment/models.py
  3. 26
      apps/payment/views.py
  4. 1
      apps/school/templates/blocks/day_pay_btn.html
  5. 2
      apps/school/templates/summer/day_pay_btn.html
  6. 2
      project/templates/blocks/messages.html
  7. 26
      project/templates/blocks/popup_buy.html
  8. 5
      project/utils.py
  9. 8
      web/src/js/modules/api.js
  10. 54
      web/src/js/modules/popup.js

@ -1,7 +1,7 @@
from django.contrib.auth import get_user_model
from rest_framework import status, views, viewsets, generics
from rest_framework.decorators import detail_route, list_route
from rest_framework.decorators import detail_route, list_route, action
from rest_framework.response import Response
from . import ExtendedModelViewSet
@ -476,6 +476,17 @@ class PaymentViewSet(ExtendedModelViewSet):
return queryset.filter(status__isnull=False).order_by('-created_at')
@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')
weekdays = request.query_params.getlist('weekdays[]')
user = user and User.objects.get(pk=user)
course = course and Course.objects.get(pk=course)
return Response(Payment.calc_amount(user=user, course=course, weekdays=weekdays))
class ContestViewSet(ExtendedModelViewSet):
queryset = Contest.objects.all()
serializer_class = ContestCreateSerializer

@ -1,4 +1,5 @@
import arrow
from django.db.models import Func, F
from paymentwall import Pingback
from polymorphic.models import PolymorphicModel
@ -11,7 +12,7 @@ from django.core.validators import RegexValidator
from django.utils.timezone import now
from django.conf import settings
from project.utils import weekday_in_date_range
from project.utils import weekdays_in_date_range
from apps.course.models import Course
from apps.config.models import Config
@ -109,6 +110,58 @@ class Payment(PolymorphicModel):
verbose_name_plural = 'Платежи'
ordering = ('created_at',)
@classmethod
def calc_amount(cls, course_payment=None, school_payment=None, user=None, course=None, weekdays=None):
if course_payment:
course = course_payment.course
user = course_payment.user
if school_payment:
user = school_payment.user
weekdays = school_payment.weekdays
discount = 0
price = 0
if course:
price = course.price
else:
school_payments = SchoolPayment.objects.filter(
user=user,
date_start__lte=now().date(),
date_end__gte=now().date(),
add_days=False,
status__in=[
Pingback.PINGBACK_TYPE_REGULAR,
Pingback.PINGBACK_TYPE_GOODWILL,
Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,
],
)
school_schedules_purchased = school_payments.annotate(
joined_weekdays=Func(F('weekdays'), function='unnest', )
).values_list('joined_weekdays', flat=True).distinct()
weekdays = set(map(int, weekdays)) - set(school_schedules_purchased)
school_schedules = SchoolSchedule.objects.filter(
weekday__in=weekdays,
)
prev_school_payment = school_payments.last()
add_days = bool(prev_school_payment)
if add_days:
weekdays_count = weekdays_in_date_range(now().date(), prev_school_payment.date_end)
all_weekdays_count = weekdays_in_date_range(prev_school_payment.date_start, prev_school_payment.date_end)
for ss in school_schedules:
price += ss.month_price // all_weekdays_count.get(ss.weekday, 0) * weekdays_count.get(
ss.weekday, 0)
else:
price = school_schedules.aggregate(
models.Sum('month_price'),
).get('month_price__sum', 0)
if not (school_payment and school_payment.id) and price >= config.SERVICE_DISCOUNT_MIN_AMOUNT:
discount = config.SERVICE_DISCOUNT
amount = price - discount
return {
'price': price,
'amount': amount,
'discount': discount,
}
def calc_commission(self):
return self.amount * config.SERVICE_COMMISSION / 100
@ -137,7 +190,8 @@ class CoursePayment(Payment):
verbose_name_plural = 'Платежи за курсы'
def save(self, *args, **kwargs):
self.amount = self.course.price
amount_data = Payment.calc_amount(course_payment=self)
self.amount = amount_data.get('amount')
super().save(*args, **kwargs)
author_balance = getattr(self, 'authorbalance', None)
if not author_balance:
@ -169,32 +223,8 @@ class SchoolPayment(Payment):
return days
def save(self, *args, **kwargs):
aggregate = SchoolSchedule.objects.filter(
weekday__in=self.weekdays,
).aggregate(
models.Sum('month_price'),
)
if self.add_days:
_school_payment = SchoolPayment.objects.filter(
add_days=False,
date_start__lte=self.date_start,
date_end__gte=self.date_end,
status__in=[
Pingback.PINGBACK_TYPE_REGULAR,
Pingback.PINGBACK_TYPE_GOODWILL,
Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,
],
).last()
weekday_count = weekday_in_date_range(self.date_start, self.date_end, self.weekdays[0])
all_weekday_count = weekday_in_date_range(_school_payment.date_start, _school_payment.date_end, self.weekdays[0])
month_price_sum = aggregate.get('month_price__sum', 0) * weekday_count // all_weekday_count
else:
month_price_sum = aggregate.get('month_price__sum', 0)
if self.id is None and month_price_sum >= config.SERVICE_DISCOUNT_MIN_AMOUNT:
discount = config.SERVICE_DISCOUNT
else:
discount = 0
self.amount = month_price_sum - discount
amount_data = Payment.calc_amount(school_payment=self)
self.amount = amount_data.get('amount')
super().save(*args, **kwargs)
@property

@ -98,7 +98,6 @@ class SchoolBuyView(TemplateView):
host = urlsplit(self.request.META.get('HTTP_REFERER'))
host = str(host[0]) + '://' + str(host[1])
weekdays = set(request.GET.getlist('weekdays', []))
add_days = 'add_days' in request.GET
roistat_visit = request.COOKIES.get('roistat_visit', None)
if not weekdays:
messages.error(request, 'Выберите несколько дней недели.')
@ -108,27 +107,30 @@ class SchoolBuyView(TemplateView):
except ValueError:
messages.error(request, 'Ошибка выбора дней недели.')
return redirect('school:summer-school')
if add_days:
_school_payment = SchoolPayment.objects.filter(
user=request.user,
date_start__lte=now().date(),
date_end__gte=now().date(),
add_days=False,
).first()
if not _school_payment:
add_days = False
prev_school_payment = SchoolPayment.objects.filter(
user=request.user,
date_start__lte=now().date(),
date_end__gte=now().date(),
add_days=False,
status__in=[
Pingback.PINGBACK_TYPE_REGULAR,
Pingback.PINGBACK_TYPE_GOODWILL,
Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,
],
).first() # ??? first?
add_days = bool(prev_school_payment)
if add_days:
school_payment = SchoolPayment.objects.create(
user=request.user,
weekdays=weekdays,
date_start=now().date(),
date_end=_school_payment.date_end,
date_end=prev_school_payment.date_end,
add_days=True,
roistat_visit=roistat_visit,
)
if school_payment.amount <= 0:
messages.error(request, 'Выбранные дни отсутствуют в оставшемся периоде подписки')
return redirect(reverse_lazy('school:summer-school'))
return redirect(reverse_lazy('school:school'))
else:
school_payment = SchoolPayment.objects.create(
user=request.user,

@ -2,5 +2,4 @@
data-popup=".js-popup-buy"
class="timing__btn btn"
data-day="{{ school_schedule.weekday }}"
href="{% url 'school-checkout' %}?weekdays={{ school_schedule.weekday }}&add_days=true"
>купить</a>

@ -3,5 +3,5 @@
data-popup=".js-popup-auth"
{% endif %}
class="timing__btn btn"
href="{% url 'school-checkout' %}?weekdays={{ school_schedule.weekday }}&add_days=true"
href="{% url 'school-checkout' %}?weekdays={{ school_schedule.weekday }}"
>купить</a>

@ -1,5 +1,5 @@
{% if messages %}
<div class="section section_gray section_menu">
<div class="section section_gray section_menu" style="margin-bottom: 20px;">
<div class="section__center center center_xs">
{% for message in messages %}
<div class="message message_{{ message.tags }}">{{ message }}</div>

@ -29,7 +29,10 @@
data-day="{{school_schedule.weekday}}"
data-price="{{school_schedule.month_price}}"
autocomplete="off"
{% if school_schedule.weekday in school_schedules_purchased or not is_purchased %}
{% if school_schedule.weekday in school_schedules_purchased %}
disabled
{% endif %}
{% if not is_purchased %}
checked
{% endif %}>
<span class="switch__content">
@ -38,8 +41,12 @@
<span class="switch__cell"></span>
<span class="switch__cell">{{ school_schedule.title }}</span>
<span class="buy__trial-lesson switch__cell">
{% if school_schedule.trial_lesson %}
<a class="js-video-modal" data-video-url="{{ school_schedule.trial_lesson }}" href="#">Пробный урок</a>
{% if school_schedule.weekday in school_schedules_purchased %}
Куплено
{% else %}
{% if school_schedule.trial_lesson %}
<a class="js-video-modal" data-video-url="{{ school_schedule.trial_lesson }}" href="">Пробный урок</a>
{% endif %}
{% endif %}
</span>
<span class="switch__cell">{{school_schedule.month_price}}р в мес.</span>
@ -55,7 +62,10 @@
data-day="{{school_schedule.weekday}}"
data-price="{{school_schedule.month_price}}"
autocomplete="off"
{% if school_schedule.weekday in school_schedules_purchased or not is_purchased %}
{% if school_schedule.weekday in school_schedules_purchased %}
disabled
{% endif %}
{% if not is_purchased %}
checked
{% endif %}>
<span class="switch__content">
@ -64,8 +74,12 @@
<span class="switch__cell"></span>
<span class="switch__cell">{{ school_schedule.title }}</span>
<span class="buy__trial-lesson switch__cell">
{% if school_schedule.trial_lesson %}
<a class="js-video-modal" data-video-url="{{ school_schedule.trial_lesson }}" href="">Пробный урок</a>
{% if school_schedule.weekday in school_schedules_purchased %}
Куплено
{% else %}
{% if school_schedule.trial_lesson %}
<a class="js-video-modal" data-video-url="{{ school_schedule.trial_lesson }}" href="">Пробный урок</a>
{% endif %}
{% endif %}
</span>
<span class="switch__cell">{{school_schedule.month_price}}р в мес.</span>

@ -13,6 +13,5 @@ def date_range(start, end):
return
def weekday_in_date_range(start, end, weekday):
counter = Counter([d.isoweekday() for d in date_range(start, end)])
return counter.get(weekday, 0)
def weekdays_in_date_range(start, end):
return Counter([d.isoweekday() for d in date_range(start, end)])

@ -502,4 +502,12 @@ export const api = {
}
});
},
getPaymentAmount: (params) => {
return api.get('/api/v1/payments/calc-amount', {
params: params,
headers: {
'Authorization': `Token ${window.LIL_STORE.accessToken}`,
}
});
}
};

@ -1,4 +1,5 @@
import $ from 'jquery';
import {api} from './api';
var selectedWeekdays = {};
$(document).ready(function () {
@ -92,7 +93,7 @@ $(document).ready(function () {
});
}
$('[data-day]').trigger('change');
updateCart();
});
$('.js-popup-close').on('click', function(e){
@ -142,43 +143,42 @@ $(document).ready(function () {
}
$(document).on('change', '[data-day]', function(){
console.log('on change data-day');
var weekday = $(this).data('day');
var price = $(this).data('price');
if($(this).is(':checked')) {
// console.log('checked');
selectedWeekdays[weekday] = {price:price};
} else {
// console.log('not checked');
delete selectedWeekdays[weekday];
}
updateCart();
});
function updateCart(){
var $orderPrice = $('.order_price_text');
var days = ['', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье'];
var weekdays = [], daysText = [], price = 0;
for(var i in selectedWeekdays) {
price += parseInt(selectedWeekdays[i].price);
weekdays.push(i);
daysText.push(days[i]);
}
var weekdays = [];
var daysText = [];
$('[data-day]').each(function() {
var weekday = $(this).data('day');
if($(this).is(':checked')) {
weekdays.push(weekday);
daysText.push(days[weekday]);
}
});
var text = '';
if(schoolAmountForDiscount <= price) {
text = '<del>'+price+'</del> '+(price-schoolDiscount)+'р.';
} else {
text = price+'p.';
if(weekdays.length){
api.getPaymentAmount({ user: window.LIL_STORE.user.id, weekdays: weekdays })
.then((response) => {
var text = '';
if(response.data.price != response.data.amount) {
text = '<del>'+response.data.price+'</del> '+response.data.amount+'р.';
} else {
text = response.data.amount+'p.';
}
$orderPrice.html(text);
});
}
$('.order_price_text').html(text);
$('.order__days').html((daysText.length) ? daysText.join(', '):'Ничего не выбрано');
else {
$orderPrice.html('0p.');
}
$('.order__days').html(daysText.length ? daysText.join(', ') : 'Ничего не выбрано');
var link = $('.but_btn_popup').data('link');
link = link+'?'+decodeURIComponent($.param({weekdays: weekdays}, true));
$('.but_btn_popup').attr('href', link);
}
updateCart();
});

Loading…
Cancel
Save