You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

225 lines
9.1 KiB

from datetime import datetime, timedelta, date
from paymentwall import Pingback
from django.contrib.auth import get_user_model
from django.contrib.auth.decorators import login_required, user_passes_test
from django.db.utils import IntegrityError
from django.db.models import Min, F, Func, Q, Value
from django.http import Http404
from django.shortcuts import get_object_or_404, redirect
from django.utils.decorators import method_decorator
from django.utils.timezone import now
from django.views.generic import ListView, UpdateView, TemplateView, DetailView
from apps.course.models import Course
from apps.payment.models import SchoolPayment
from .models import LiveLesson, SchoolSchedule
User = get_user_model()
def is_admin_or_teacher(function=None, login_url=None):
actual_decorator = user_passes_test(
lambda u: u.role in [User.ADMIN_ROLE, User.TEACHER_ROLE], login_url=login_url
)
if function:
return actual_decorator(function)
return actual_decorator
@method_decorator([login_required, is_admin_or_teacher], name='dispatch')
class LiveLessonsView(ListView):
model = LiveLesson
template_name = 'school/livelessons_list.html'
def get_queryset(self):
september2018 = date(2018, 9, 1)
date_start = (now() - timedelta(days=7)).date()
if date_start < september2018:
date_start = september2018
date_range = Q(
date__range=[
date_start,
date_start + timedelta(days=17),
]
)
queryset = LiveLesson.objects.filter(date_range)
if queryset.count() < 17:
for i in range(18):
try:
LiveLesson.objects.create(
date=date_start + timedelta(days=i),
)
except IntegrityError:
pass
queryset = LiveLesson.objects.filter(date_range)
return queryset
class LiveLessonsDetailView(DetailView):
model = LiveLesson
template_name = 'school/livelesson_detail.html'
def get(self, request, pk=None):
self.object = self.get_object()
if request.user.is_authenticated:
is_purchased = SchoolPayment.objects.filter(
user=request.user,
date_start__lte=now(),
date_end__gte=now() - timedelta(days=7),
status__in=[
Pingback.PINGBACK_TYPE_REGULAR,
Pingback.PINGBACK_TYPE_GOODWILL,
Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,
],
weekdays__contains=[self.object.date.weekday() + 1],
).exists()
if not is_purchased and request.user.role not in [User.ADMIN_ROLE, User.TEACHER_ROLE]:
raise Http404
else:
self.template_name = 'school/livelesson_detail_unauth.html'
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
@method_decorator([login_required, is_admin_or_teacher], name='dispatch')
class LiveLessonEditView(TemplateView):
template_name = 'course/course_edit.html'
def get(self, request, pk=None):
if pk:
self.object = get_object_or_404(LiveLesson, pk=pk)
else:
try:
self.object = LiveLesson.objects.get(date=now().date())
except LiveLesson.DoesNotExist:
self.object = LiveLesson.objects.create()
return super().get(request)
def get_context_data(self):
context = super().get_context_data()
context['object'] = self.object
context['live'] = 'true'
return context
class SchoolView(TemplateView):
template_name = 'school/summer_school.html'
def get_context_data(self):
context = super().get_context_data()
date_now = now().date()
now_time = now()
try:
school_schedule = SchoolSchedule.objects.get(weekday=now_time.isoweekday())
except SchoolSchedule.DoesNotExist:
online = False
else:
end_at = datetime.combine(now_time.today(), school_schedule.start_at)
online = (
school_schedule.start_at <= now_time.time() and
(end_at + timedelta(hours=1)).time() >= now_time.time() and
school_schedule.current_live_lesson
)
school_schedules = SchoolSchedule.objects.all()
try:
school_schedules_sorted = sorted(school_schedules,
key=lambda ss: ss.current_live_lesson and ss.current_live_lesson.date)
except Exception:
school_schedules_sorted = school_schedules
prev_live_lessons = []
prev_live_lessons_exists = False
subscription_ends = None
school_payment_exists = False
school_schedules_purchased = []
school_purchased_future = False
prev_school_payments = None
prev_range = [date_now - timedelta(days=8), date_now]
if self.request.user.is_authenticated:
school_payment = SchoolPayment.objects.filter(
user=self.request.user,
status__in=SchoolPayment.PW_PAID_STATUSES,
date_start__lte=date_now,
date_end__gte=date_now
)
school_payment_exists = school_payment.exists()
school_purchased_future = SchoolPayment.objects.filter(
user=self.request.user,
status__in=SchoolPayment.PW_PAID_STATUSES,
date_start__gt=date_now,
date_end__gt=date_now
)
if school_purchased_future.exists():
subscription_ends = school_purchased_future.filter(add_days=False).latest(
'date_end').date_end
elif school_payment_exists:
subscription_ends = school_payment.filter(add_days=False).latest('date_end').date_end
school_schedules_purchased = school_payment.annotate(
joined_weekdays=Func(F('weekdays'), function='unnest',)
).values_list('joined_weekdays', flat=True).distinct()
prev_school_payments = SchoolPayment.objects.filter(
date_start__lt=prev_range[1],
date_end__gte=prev_range[0],
user=self.request.user,
status__in=[
Pingback.PINGBACK_TYPE_REGULAR,
Pingback.PINGBACK_TYPE_GOODWILL,
Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,
],
weekdays__len__gt=0,
)
# берем все подписки, которые были в периоде
for sp in prev_school_payments:
# берем все уроки в оплаченном промежутке
date_range = [max(sp.date_start, prev_range[0]), min(sp.date_end, prev_range[1])]
prev_live_lessons = LiveLesson.objects.filter(
date__range=date_range,
deactivated_at__isnull=True,
date__week_day__in=list(map(lambda x: 1 if x == 7 else x+1, sp.weekdays)),
).values_list('id', flat=True)
prev_live_lessons = LiveLesson.objects.filter(id__in=set(prev_live_lessons)).order_by('-date')
prev_live_lessons_exists = prev_live_lessons.exists()
if prev_live_lessons_exists:
school_schedules_dict = {ss.weekday: ss for ss in school_schedules}
school_schedules_dict[0] = school_schedules_dict.get(7)
for ll in prev_live_lessons:
ll.school_schedule = school_schedules_dict.get(ll.date.isoweekday())
else:
prev_live_lessons = []
context.update({
'online': online,
'prev_live_lessons': prev_live_lessons,
'prev_live_lessons_exists': prev_live_lessons_exists,
'course_items': Course.objects.filter(status=Course.PUBLISHED)[:6],
'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': school_purchased_future,
'prev_school_payments_exists': prev_school_payments and prev_school_payments.exists(),
'subscription_ends': subscription_ends,
'prolong_date_start': subscription_ends + timedelta(days=1) if subscription_ends else None,
'allow_prolong': subscription_ends - date_now <= timedelta(days=7)
if not school_purchased_future and subscription_ends else False,
})
return context
class SchoolSchedulesPrintView(TemplateView):
template_name = 'school/schedules_print.html'
def get_context_data(self):
context = super().get_context_data()
context['school_schedules'] = SchoolSchedule.objects.all()
return context