diff --git a/apps/school/fixtures/school_schedules.json b/apps/school/fixtures/school_schedules.json index 9841f8eb..8cba4ef4 100644 --- a/apps/school/fixtures/school_schedules.json +++ b/apps/school/fixtures/school_schedules.json @@ -34,7 +34,7 @@ "pk": 3, "fields": { "weekday": 3, - "title": "Пластелин", + "title": "Пластилин", "short_description": "Однажды он затеял скандал на торговой площади ради леденца", "description": "Однажды он затеял скандал на торговой площади ради леденца, вокруг собралась толпа, и полицейские попросили хозяина лавки открыть её во время сиесты и подарить мальчику сладость.", "materials": "Он добивался своего капризами и симуляцией, всегда стремился выделиться и привлечь к себе внимание.", diff --git a/apps/school/migrations/0012_auto_20180417_1344.py b/apps/school/migrations/0012_auto_20180417_1344.py new file mode 100644 index 00000000..4b0d1032 --- /dev/null +++ b/apps/school/migrations/0012_auto_20180417_1344.py @@ -0,0 +1,17 @@ +# Generated by Django 2.0.3 on 2018-04-17 10:44 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('school', '0011_schoolschedule_short_description'), + ] + + operations = [ + migrations.AlterModelOptions( + name='schoolscheduleimage', + options={'ordering': ('-created_at',), 'verbose_name': 'Изображение работ', 'verbose_name_plural': 'Изображения работ'}, + ), + ] diff --git a/apps/school/models.py b/apps/school/models.py index 867ad447..6527ccc4 100644 --- a/apps/school/models.py +++ b/apps/school/models.py @@ -1,9 +1,10 @@ from django.db import models +from django.utils.timezone import now from project.mixins import BaseModel, DeactivatedMixin from apps.content.models import ImageObject -from apps.course.models import Comment +from apps.payment import models as payment_models class SchoolSchedule(models.Model): @@ -16,14 +17,20 @@ class SchoolSchedule(models.Model): (6, 'суббота'), (7, 'воскресенье'), ) - weekday = models.PositiveSmallIntegerField('День недели', choices=WEEKDAY_CHOICES, unique=True) + weekday = models.PositiveSmallIntegerField( + 'День недели', choices=WEEKDAY_CHOICES, unique=True + ) title = models.CharField('Заголовок', default='', max_length=100, db_index=True) - short_description = models.CharField('Короткое описание', default='', max_length=100, db_index=True) + short_description = models.CharField( + 'Короткое описание', default='', max_length=100, db_index=True + ) description = models.TextField('Описание') materials = models.TextField('Материалы') age = models.PositiveSmallIntegerField('Возраст', default=0) month_price = models.DecimalField('Цена', max_digits=8, decimal_places=2, default=0) - day_discount = models.DecimalField('Скидка, в валюте', max_digits=8, decimal_places=2, default=0) + day_discount = models.DecimalField( + 'Скидка, в валюте', max_digits=8, decimal_places=2, default=0 + ) start_at = models.TimeField('Начало урока', null=True) class Meta: @@ -34,16 +41,45 @@ class SchoolSchedule(models.Model): def __str__(self): return dict(self.WEEKDAY_CHOICES).get(self.weekday, '') + def is_online(self): + return now().isoweekday() == self.weekday and now().time() >= self.start_at + + def is_purchased(self): + try: + school_payment = payment_models.SchoolPayment.objects.get( + weekdays__contains=[self.weekday], + date_start__gte=now().date(), + date_end__lte=now().date(), + ) + except payment_models.SchoolPayment.DoesNotExist: + return False + else: + return school_payment.is_deliverable() + + def current_live_lesson(self): + now_time = now() + weekday = self.weekday + live_lesson = LiveLesson.objects.filter( + date__week_day=weekday + 1 if weekday % 7 else 1, + date__gte=now_time.date(), + ).first() + return live_lesson + class SchoolScheduleImage(models.Model): schoolschedule = models.ForeignKey( - SchoolSchedule, on_delete=models.CASCADE, - verbose_name='День занятия', related_name='schoolschedule_images' + SchoolSchedule, + on_delete=models.CASCADE, + verbose_name='День занятия', + related_name='schoolschedule_images', ) img = models.ForeignKey( - ImageObject, related_name='schoolschedule_images', - verbose_name='Объект изображения', on_delete=models.CASCADE, - null=True, blank=True, + ImageObject, + related_name='schoolschedule_images', + verbose_name='Объект изображения', + on_delete=models.CASCADE, + null=True, + blank=True, ) created_at = models.DateTimeField(auto_now_add=True) @@ -61,9 +97,12 @@ class LiveLesson(BaseModel, DeactivatedMixin): stream = models.URLField('Ссылка на VIMEO', default='', blank=True) date = models.DateField(null=True, blank=True) cover = models.ForeignKey( - ImageObject, related_name='livelesson_covers', - verbose_name='Обложка урока школы', on_delete=models.CASCADE, - null=True, blank=True, + ImageObject, + related_name='livelesson_covers', + verbose_name='Обложка урока школы', + on_delete=models.CASCADE, + null=True, + blank=True, ) created_at = models.DateTimeField(auto_now_add=True) diff --git a/apps/school/templates/blocks/schedule.html b/apps/school/templates/blocks/schedule.html index da3c2db9..ae7f231d 100644 --- a/apps/school/templates/blocks/schedule.html +++ b/apps/school/templates/blocks/schedule.html @@ -1,31 +1,44 @@ {% load static %} +{% load thumbnail %}
Расписание
{% for school_schedule in school_schedules %} + {% with current_live_lesson=school_schedule.current_live_lesson %}
-
{{ school_schedule }}
-
2 апреля
+
+ {{ school_schedule }} +
+ {% if current_live_lesson %} +
{{ current_live_lesson.date }}
+ {% endif %}
-
17:00 (МСК)
- купить +
{{ school_schedule.start_at }} (МСК)
+ {% include './pay_btn.html' %}
- + {% thumbnail current_live_lesson.cover.image "70x70" crop="center" as im %} + + {% empty %} + + {% endthumbnail %}
-
{{ school_schedule.title }}, - Санкт-Петербург +
{{ school_schedule.title }}{% if current_live_lesson %}, + {{ current_live_lesson.title }} + {% endif %}
-
{{ school_schedule.short_description }}
+ {% if current_live_lesson %} +
{{ current_live_lesson.short_description }}
+ {% endif %}
Материалы
@@ -45,7 +58,9 @@
{% for image in school_schedule.schoolschedule_images.all %} - + {% thumbnail image.img.image "48x48" crop="center" as im %} + + {% endthumbnail %} {% endfor %}
@@ -60,6 +75,7 @@
+ {% endwith %} {% endfor %} {% comment %}
@@ -516,7 +532,7 @@ {% endcomment %}
- купить + {% include './pay_btn.html' %} Распечатать расписание чтобы не забыть diff --git a/apps/school/views.py b/apps/school/views.py index 422eeaf6..30194597 100644 --- a/apps/school/views.py +++ b/apps/school/views.py @@ -1,10 +1,13 @@ from django.contrib.auth import get_user_model from django.contrib.auth.decorators import login_required, user_passes_test from django.db.models import Min +from django.http import Http404 from django.shortcuts import get_object_or_404 from django.utils.decorators import method_decorator +from django.utils.timezone import now from django.views.generic import ListView, UpdateView, TemplateView, DetailView +from apps.payment.models import SchoolPayment from .models import LiveLesson, SchoolSchedule User = get_user_model() @@ -12,11 +15,11 @@ 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, + lambda u: u.role in [User.ADMIN_ROLE, User.TEACHER_ROLE], login_url=login_url ) if function: return actual_decorator(function) + return actual_decorator @@ -26,11 +29,28 @@ class LiveLessonsView(ListView): template_name = 'school/livelessons_list.html' -@method_decorator([login_required, is_admin_or_teacher], name='dispatch') +@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, date_start__gte=now(), date__end__lte=now() + ) + except SchoolPayment.DoesNotExist: + school_payment = None + if request.user.role not in [User.ADMIN_ROLE, User.TEACHER_ROLE] or 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): @@ -57,6 +77,6 @@ class SchoolView(TemplateView): context = super().get_context_data() context.update({ 'school_schedules': SchoolSchedule.objects.all(), - 'min_school_price': SchoolSchedule.objects.all().aggregate(Min('month_price'))['month_price__min'], + 'min_school_price': SchoolSchedule.objects.aggregate(Min('month_price'))['month_price__min'], }) return context diff --git a/project/templates/blocks/header.html b/project/templates/blocks/header.html index a020fe91..ea813ae9 100644 --- a/project/templates/blocks/header.html +++ b/project/templates/blocks/header.html @@ -1,4 +1,4 @@ -{% load static %} {% load active_link_tags %} {% load category_menu_items from lilcity_category %} +{% load static %} {% load thumbnail %} {% load active_link_tags %} {% load category_menu_items from lilcity_category %}
@@ -27,8 +27,9 @@