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 @method_decorator(login_required, name='dispatch') class LiveLessonsDetailView(DetailView): model = LiveLesson template_name = 'school/livelesson_detail.html' def get(self, request, pk=None): response = super().get(request, pk=pk) # ??? где проверка? #try: # school_payment = SchoolPayment.objects.get( # user=request.user, # add_days=False, # date_start__lte=now(), # date_end__gte=now(), # status__in=[ # Pingback.PINGBACK_TYPE_REGULAR, # Pingback.PINGBACK_TYPE_GOODWILL, # Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED, # ], # ) #except SchoolPayment.DoesNotExist: # school_payment = None #if request.user.role not in [User.ADMIN_ROLE, User.TEACHER_ROLE] and not ( # request.user.role == User.USER_ROLE and # school_payment and # school_payment.is_deliverable() #): # raise Http404 return response @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() is_previous = 'is_previous' in self.request.GET date_now = now().date() yesterday = date_now - timedelta(days=1) # month_start = date_now.replace(day=1) month_start = datetime(2018, 7, 1).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(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} school_schedules_dict[0] = school_schedules_dict.get(7) live_lessons = None live_lessons_exists = False if self.request.user.is_authenticated: school_payment = SchoolPayment.objects.filter( user=self.request.user, status__in=[ Pingback.PINGBACK_TYPE_REGULAR, Pingback.PINGBACK_TYPE_GOODWILL, Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED, ], date_start__lte=date_now, date_end__gte=date_now ) school_payment_exists = school_payment.exists() school_schedules_purchased = school_payment.annotate( joined_weekdays=Func(F('weekdays'), function='unnest',) ).values_list('joined_weekdays', flat=True).distinct() else: school_payment_exists = False school_schedules_purchased = [] if is_previous: prev_range = [yesterday - timedelta(days=7), yesterday] live_lessons = [] # берем все подписки, которые были в периоде for sp in SchoolPayment.objects.filter( date_start__lte=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, ], ): # берем все уроки в оплаченном промежутке date_range = [max(sp.date_start, prev_range[0]), min(sp.date_end, prev_range[1])] 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) live_lessons = LiveLesson.objects.filter(id__in=set(live_lessons)).order_by('-date') for ll in live_lessons: ll.school_schedule = school_schedules_dict.get(ll.date.isoweekday()) live_lessons_exists = live_lessons.exists() live_lessons = live_lessons or None context.update({ 'online': online, 'live_lessons': live_lessons, 'live_lessons_exists': live_lessons_exists, 'is_previous': is_previous, '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': school_schedules, 'school_schedules_purchased': school_schedules_purchased, 'school_purchased_future': False, 'subscription_ends': school_payment.filter(add_days=False).first().date_end if school_payment_exists else None, }) 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