рисовальный лагерь

remotes/origin/feature/cat-title-links-24-05-19
gzbender 7 years ago
parent dd57cac5d6
commit d7fb5568b8
  1. 4
      api/v1/views.py
  2. 2
      apps/course/templates/course/course_edit.html
  3. 27
      apps/payment/migrations/0036_drawingcamppayment.py
  4. 70
      apps/payment/models.py
  5. 6
      apps/payment/templates/payment/payment_success.html
  6. 91
      apps/payment/views.py
  7. 1
      apps/school/admin.py
  8. 18
      apps/school/migrations/0023_livelesson_is_camp.py
  9. 32
      apps/school/models.py
  10. 4
      apps/school/templates/blocks/day_pay_btn.html
  11. 2
      apps/school/templates/blocks/schedule.html
  12. 6
      apps/school/templates/blocks/schedule_item.html
  13. 20
      apps/school/templates/blocks/schedule_purchased.html
  14. 30
      apps/school/templates/drawing_camp/about.html
  15. 65
      apps/school/templates/drawing_camp/gallery.html
  16. 9
      apps/school/templates/drawing_camp/online.html
  17. 27
      apps/school/templates/drawing_camp/promo.html
  18. 62
      apps/school/templates/drawing_camp/schedule_purchased.html
  19. 16
      apps/school/templates/school/drawing_camp.html
  20. 5
      apps/school/templates/school/livelessons_list.html
  21. 2
      apps/school/templates/summer/promo.html
  22. 6
      apps/school/templates/summer/schedule_purchased.html
  23. 12
      apps/school/urls.py
  24. 189
      apps/school/views.py
  25. 3
      project/templates/blocks/footer.html
  26. 10
      project/templates/blocks/header.html
  27. 7
      project/templates/blocks/popup_school_buy.html
  28. 25
      project/templates/blocks/promo.html
  29. 3
      project/templates/blocks/user_menu.html
  30. 8
      project/urls.py
  31. 25
      project/views.py
  32. 6
      web/src/components/CourseRedactor.vue
  33. 11
      web/src/js/modules/popup.js

@ -643,11 +643,13 @@ class PaymentViewSet(viewsets.ModelViewSet):
course = request.query_params.get('course')
weekdays = request.query_params.getlist('weekdays[]')
date_start = request.query_params.get('date_start')
is_camp = bool(request.query_params.get('is_camp'))
user = user and User.objects.get(pk=user)
course = course and Course.objects.get(pk=course)
date_start = date_start and datetime.strptime(date_start, '%Y-%m-%d')
return Response(Payment.calc_amount(user=user, course=course, date_start=date_start, weekdays=weekdays))
return Response(Payment.calc_amount(user=user, course=course, date_start=date_start, weekdays=weekdays,
is_camp=is_camp))
class ContestViewSet(ExtendedModelViewSet):

@ -17,7 +17,7 @@
{% endblock header_buttons %}
{% block content %}
<course-redactor name="course-redactor" :live="{{ live }}"
<course-redactor name="course-redactor" :live="{{ live }}" :camp="{{ is_camp }}"
author-picture="{% if request.user.photo %}{{ request.user.photo.url }}{% else %}{% static 'img/user_default.jpg' %}{% endif %}"
author-name="{{ request.user.first_name }} {{ request.user.last_name }}"
access-token="{{ request.user.auth_token }}"

@ -0,0 +1,27 @@
# Generated by Django 2.0.7 on 2019-05-07 01:31
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('payment', '0035_auto_20190405_1828'),
]
operations = [
migrations.CreateModel(
name='DrawingCampPayment',
fields=[
('payment_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='payment.Payment')),
('date_start', models.DateField(blank=True, null=True, verbose_name='Дата начала подписки')),
('date_end', models.DateField(blank=True, null=True, verbose_name='Дата окончания подписки')),
],
options={
'verbose_name': 'Платеж за рисовальный лагерь',
'verbose_name_plural': 'Платежи за рисовальный лагерь',
},
bases=('payment.payment',),
),
]

@ -1,3 +1,6 @@
from datetime import timedelta, date
from decimal import Decimal
import arrow
import short_url
@ -122,7 +125,10 @@ class Payment(PolymorphicModel):
ordering = ('created_at',)
@classmethod
def add_months(cls, sourcedate, months=1):
def add_months(cls, sourcedate, months=1, is_camp=False):
# Лагерь всегда до коонца месяца покупается
if is_camp:
return arrow.get(sourcedate.replace(day=1), settings.TIME_ZONE).shift(months=months).date() - timedelta(1)
# FIXME после мая 2019 убрать?
# Если хотят купить школу в мае, то оплатить ее можно только до 31 мая, потом школа закроется
if sourcedate.month == 5:
@ -135,9 +141,31 @@ class Payment(PolymorphicModel):
return result.datetime
@classmethod
def calc_amount(cls, payment=None, user=None, course=None, date_start=None, weekdays=None):
def get_date_range(cls, date_start=None, days=0, months=0, is_camp=False):
school_start = date(now().year, 9, 1)
school_end = date(now().year, 5, 31)
camp_start = date(now().year, 6, 1)
camp_end = date(now().year, 8, 31)
date_start = date_start or now().date()
date_end = Payment.add_months(date_start, 1)
if is_camp:
if date_start < camp_start:
date_start = camp_start
elif school_end < date_start < school_start:
date_start = school_start
date_end = arrow.get(date_start + timedelta(days=days), settings.TIME_ZONE).shift(months=months).date() - timedelta(1)
if months == 1:
if is_camp or (date_start.month == 2 and date_start.day >= 28) or (date_start.day == 31 and date_end.day <= 30) \
or (date_start.month == 1 and date_start.day >= 29 and date_end.day == 28):
date_end = date_start.replace(day=1, month=date_start.month + 1) - timedelta(1)
if is_camp:
if date_end > camp_end:
date_end = camp_end
elif school_end < date_end < school_start:
date_end = school_end
return [date_start, date_end]
@classmethod
def calc_amount(cls, payment=None, user=None, course=None, date_start=None, weekdays=None, is_camp=False):
price = 0
discount = 0
referral_bonus = 0
@ -149,6 +177,12 @@ class Payment(PolymorphicModel):
user = payment.user
weekdays = payment.weekdays
date_start = payment.date_start
if isinstance(payment, DrawingCampPayment):
user = payment.user
date_start = payment.date_start
if issubclass(cls, DrawingCampPayment):
is_camp = True
date_start, date_end = Payment.get_date_range(date_start, months=1, is_camp=is_camp)
if hasattr(user, 'referral') and not user.referral.payment:
referral_bonus = user.referral.bonus
referrer_bonus = user.referral.referrer_bonus
@ -159,6 +193,15 @@ class Payment(PolymorphicModel):
elif course:
paid_before = CoursePayment.objects.filter(user=user, course=course, status__in=Payment.PW_PAID_STATUSES).exists()
price = course.price / 2 if paid_before else course.price
elif is_camp:
if date_start.day == 1:
price = DrawingCampPayment.MONTH_PRICE
else:
weekdays_count = weekdays_in_date_range(date_start, date_end)
weekdays_count = sum(weekdays_count[wd] for wd in DrawingCampPayment.WEEKDAYS)
all_weekdays_count = weekdays_in_date_range(date_start.replace(day=1), date_end)
all_weekdays_count = sum(all_weekdays_count[wd] for wd in DrawingCampPayment.WEEKDAYS)
price = round(DrawingCampPayment.MONTH_PRICE / all_weekdays_count * weekdays_count)
else:
if user:
school_payments = SchoolPayment.objects.filter(
@ -242,7 +285,7 @@ class Payment(PolymorphicModel):
]
def save(self, *args, **kwargs):
amount_data = Payment.calc_amount(payment=self)
amount_data = type(self).calc_amount(payment=self)
if not self.is_paid():
if not self.bonus:
self.amount = amount_data.get('amount')
@ -309,6 +352,25 @@ class SchoolPayment(Payment):
return arrow.get(self.date_end, settings.TIME_ZONE).humanize(locale='ru')
class DrawingCampPayment(Payment):
MONTH_PRICE = Decimal(1490)
WEEKDAYS = {1, 3, 5}
date_start = models.DateField('Дата начала подписки', null=True, blank=True)
date_end = models.DateField('Дата окончания подписки', null=True, blank=True)
class Meta:
verbose_name = 'Платеж за рисовальный лагерь'
verbose_name_plural = 'Платежи за рисовальный лагерь'
def __str__(self):
return '%s - %s' % (self.date_start.strftime('%d/%m/%Y'), self.date_end.strftime('%d/%m/%Y'))
@property
def date_end_humanize(self):
return arrow.get(self.date_end, settings.TIME_ZONE).humanize(locale='ru')
class GiftCertificatePayment(Payment):
gift_certificate = models.ForeignKey('GiftCertificate', on_delete=models.CASCADE,
verbose_name='Подарочный сертификат', related_name='payments')

@ -8,6 +8,12 @@
<a class="done__btn btn btn_md btn_stroke" href="{% url 'school:school' %}">ПЕРЕЙТИ К ШКОЛЕ</a>
</div>
{% endif %}
{% if camp %}
<div class="done__title title">Вы успешно приобрели доступ к урокам рисовального лагеря!</div>
<div class="done__foot">
<a class="done__btn btn btn_md btn_stroke" href="{% url 'school:drawing-camp' %}">ПЕРЕЙТИ В ЛАГЕРЬ</a>
</div>
{% endif %}
{% if course %}
<div class="done__title title">Вы успешно приобрели курс!</div>
<div class="done__foot">

@ -28,7 +28,7 @@ from apps.school.models import SchoolSchedule
from apps.payment.tasks import transaction_to_mixpanel, product_payment_to_mixpanel, transaction_to_roistat
from .models import AuthorBalance, CoursePayment, SchoolPayment, Payment, UserBonus, GiftCertificate, \
GiftCertificatePayment, UserGiftCertificate
GiftCertificatePayment, UserGiftCertificate, DrawingCampPayment
logger = logging.getLogger('django')
@ -50,8 +50,8 @@ class CourseBuySuccessView(TemplateView):
class SchoolBuySuccessView(TemplateView):
template_name = 'payment/payment_success.html'
def get(self, request, pk=None, *args, **kwargs):
return self.render_to_response(context={'school': True})
def get(self, request, pk=None, is_camp=False, *args, **kwargs):
return self.render_to_response(context={'camp': True} if is_camp else {'school': True})
@method_decorator(login_required, name='dispatch')
@ -119,13 +119,15 @@ class SchoolBuyView(TemplateView):
template_name = 'payment/paymentwall_widget.html'
def get(self, request, *args, **kwargs):
raise Http404() # FIXME
host = urlsplit(self.request.META.get('HTTP_REFERER'))
host = str(host[0]) + '://' + str(host[1])
weekdays = set(request.GET.getlist('weekdays', []))
use_bonuses = request.GET.get('use_bonuses')
roistat_visit = request.COOKIES.get('roistat_visit', None)
date_start = request.GET.get('date_start')
date_start = date_start and datetime.datetime.strptime(date_start, '%Y-%m-%d') or now().date()
date_start = date_start and datetime.datetime.strptime(date_start, '%Y-%m-%d').date() or now().date()
date_start, date_end = Payment.get_date_range(date_start, months=1)
if not weekdays:
messages.error(request, 'Выберите несколько дней недели.')
return redirect('school:school')
@ -165,7 +167,7 @@ class SchoolBuyView(TemplateView):
weekdays=weekdays,
roistat_visit=roistat_visit,
date_start=date_start,
date_end=Payment.add_months(date_start),
date_end=date_end,
)
if use_bonuses and request.user.bonus:
if request.user.bonus >= school_payment.amount:
@ -203,6 +205,73 @@ class SchoolBuyView(TemplateView):
return self.render_to_response(context={'widget': widget.get_html_code()})
@method_decorator(login_required, name='dispatch')
class DrawingCampBuyView(TemplateView):
template_name = 'payment/paymentwall_widget.html'
def get(self, request, *args, **kwargs):
host = urlsplit(self.request.META.get('HTTP_REFERER'))
host = str(host[0]) + '://' + str(host[1])
use_bonuses = request.GET.get('use_bonuses')
roistat_visit = request.COOKIES.get('roistat_visit', None)
date_start = request.GET.get('date_start')
date_start = date_start and datetime.datetime.strptime(date_start, '%Y-%m-%d').date() or now().date()
date_start, date_end = Payment.get_date_range(date_start, months=1, is_camp=True)
prev_payment = DrawingCampPayment.objects.filter(
user=request.user,
date_start__lte=date_start,
date_end__gte=date_start,
status__in=[
Pingback.PINGBACK_TYPE_REGULAR,
Pingback.PINGBACK_TYPE_GOODWILL,
Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,
],
).exists()
if prev_payment:
return HttpResponse(status=403)
camp_payment = DrawingCampPayment.objects.create(
user=request.user,
roistat_visit=roistat_visit,
date_start=date_start,
date_end=date_end,
)
if use_bonuses and request.user.bonus:
if request.user.bonus >= camp_payment.amount:
bonus = UserBonus.objects.create(amount=-camp_payment.amount, user=request.user,
payment=camp_payment)
camp_payment.amount = 0
camp_payment.status = Pingback.PINGBACK_TYPE_REGULAR
else:
bonus = UserBonus.objects.create(amount=-request.user.bonus, user=request.user,
payment=camp_payment)
camp_payment.amount -= request.user.bonus
camp_payment.bonus = bonus
camp_payment.save()
if camp_payment.is_paid():
return redirect(reverse_lazy('camp-payment-success'))
product = Product(
f'drawing_camp_{camp_payment.id}',
camp_payment.amount,
'RUB',
'Школа',
)
widget = Widget(
str(request.user.id),
'p1_1',
[product],
extra_params={
'email': request.user.email,
'lang': 'ru',
'evaluation': 1,
'demo': 1,
'test_mode': 1,
'success_url': host + str(reverse_lazy('camp-payment-success')),
'failure_url': host + str(reverse_lazy('payment-error')),
}
)
return self.render_to_response(context={'widget': widget.get_html_code()})
@method_decorator(csrf_exempt, name='dispatch')
class PaymentwallCallbackView(View):
@ -226,6 +295,8 @@ class PaymentwallCallbackView(View):
product_payment_class = CoursePayment
elif product_type_name == 'school':
product_payment_class = SchoolPayment
elif product_type_name == 'drawing_camp':
product_payment_class = DrawingCampPayment
elif product_type_name == 'gift_certificate':
product_payment_class = GiftCertificatePayment
else:
@ -276,6 +347,16 @@ class PaymentwallCallbackView(View):
'created_at': payment.created_at,
'update_at': payment.update_at,
}
elif product_type_name == 'drawing_camp':
properties = {
'payment_id': payment.id,
'amount': payment.amount,
'status': payment.status,
'date_start': payment.date_start,
'date_end': payment.date_end,
'created_at': payment.created_at,
'update_at': payment.update_at,
}
elif product_type_name == 'gift_certificate':
properties = {
'payment_id': payment.id,

@ -11,6 +11,7 @@ class LiveLessonAdmin(admin.ModelAdmin):
'stream',
'cover',
'date',
'is_camp',
'created_at',
'update_at',
)

@ -0,0 +1,18 @@
# Generated by Django 2.0.7 on 2019-05-07 04:42
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('school', '0022_livelesson_materials'),
]
operations = [
migrations.AddField(
model_name='livelesson',
name='is_camp',
field=models.BooleanField(default=False),
),
]

@ -69,6 +69,7 @@ class SchoolSchedule(models.Model):
date__week_day=self.weekday % 7 + 1,
date__range=[date_start, date_start + timedelta(days=6)],
deactivated_at__isnull=True,
is_camp=False,
).first()
return live_lesson
@ -79,6 +80,29 @@ class SchoolSchedule(models.Model):
date__week_day=self.weekday % 7 + 1,
date__range=[(now_time - timedelta(days=8)).date(), (now_time - timedelta(days=1)).date()],
deactivated_at__isnull=True,
is_camp=False,
).first()
return live_lesson
@cached_property
def current_camp_lesson(self):
date_start = now().date()
live_lesson = LiveLesson.objects.filter(
date__week_day=self.weekday % 7 + 1,
date__range=[date_start, date_start + timedelta(days=6)],
deactivated_at__isnull=True,
is_camp=True,
).first()
return live_lesson
@cached_property
def previous_camp_lesson(self):
now_time = now()
live_lesson = LiveLesson.objects.filter(
date__week_day=self.weekday % 7 + 1,
date__range=[(now_time - timedelta(days=8)).date(), (now_time - timedelta(days=1)).date()],
deactivated_at__isnull=True,
is_camp=True,
).first()
return live_lesson
@ -126,6 +150,7 @@ class LiveLesson(BaseModel, DeactivatedMixin):
null=True,
blank=True,
)
is_camp = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
@ -148,16 +173,17 @@ class LiveLesson(BaseModel, DeactivatedMixin):
return self.get_absolute_url()
def get_absolute_url(self):
return reverse_lazy('school:lesson-detail', kwargs={'lesson_date': self.date.strftime('%d-%m-%y')})
return (reverse_lazy('school:camp-lesson-detail', kwargs={'lesson_date': self.date.strftime('%d-%m-%y')})
if self.is_camp
else reverse_lazy('school:lesson-detail', kwargs={'lesson_date': self.date.strftime('%d-%m-%y')}))
def stream_index(self):
return self.stream.split('/')[-1]
@cached_property
def school_schedule(self):
weekday = self.date.isoweekday() if self.date else None
try:
return SchoolSchedule.objects.get(weekday=weekday)
return SchoolSchedule.objects.get(weekday=self.date.isoweekday())
except SchoolSchedule.DoesNotExist:
return None

@ -1,5 +1,9 @@
<a
data-popup=".js-popup-buy"
class="timing__btn btn"
{% if is_drawing_camp %}
data-is-camp="1"
{% else %}
data-day="{{ school_schedule.weekday }}"
{% endif %}
>купить</a>

@ -10,6 +10,7 @@
{% endfor %}
</div>
<div class="timing__foot">
{% comment %}
{% if not is_purchased and not is_purchased_future %}
<a data-popup=".js-popup-buy" class="btn" href="#">Получить доступ на месяц</a>
{% endif %}
@ -19,6 +20,7 @@
<use xlink:href="{% static 'img/sprite.svg' %}#icon-print"></use>
</svg>
</a>
{% endcomment %}
</div>
</div>
</div>

@ -20,9 +20,11 @@
{% include './open_lesson.html' %}
{% endif %}
{% else %}
{% include './day_pay_btn.html' %}
{% if not is_purchased_future and is_drawing_camp %}
{% include './day_pay_btn.html' %}
{% endif %}
{% endif %}
{% if not is_purchased and not request.user_agent.is_mobile and school_schedule.trial_lesson %}
{% if not is_purchased and not request.user_agent.is_mobile and school_schedule.trial_lesson and not is_drawing_camp %}
<a class="timing__trial-lesson js-video-modal" href="#" data-trial-lesson="1" data-video-url="{{ school_schedule.trial_lesson }}">Пробный урок</a>
{% endif %}
</div>

@ -40,15 +40,17 @@
{% if is_previous and not live_lessons_exists %}
Записей уроков пока нет
{% else %}
{% for school_schedule in school_schedules %}
{% if is_previous %}
{% if school_schedule.previous_live_lesson in live_lessons %}
{% include 'blocks/schedule_item.html' with school_schedule=school_schedule live_lesson=school_schedule.previous_live_lesson purchased=True %}
{% endif %}
{% else %}
{% include 'blocks/schedule_item.html' with school_schedule=school_schedule live_lesson=school_schedule.current_live_lesson purchased=True %}
{% endif %}
{% endfor %}
{% for school_schedule in school_schedules %}
{% if is_previous %}
{% if school_schedule.previous_live_lesson in live_lessons %}
{% include 'blocks/schedule_item.html' with school_schedule=school_schedule
live_lesson=school_schedule.previous_live_lesson purchased=True %}
{% endif %}
{% else %}
{% include 'blocks/schedule_item.html' with school_schedule=school_schedule
live_lesson=school_schedule.current_live_lesson purchased=True %}
{% endif %}
{% endfor %}
{% endif %}
</div>
<div class="timing__week">

@ -0,0 +1,30 @@
{% load static %}
<div class="section" id="about">
<div class="section__center center">
<div class="title title_center">О Рисовальном Лагере</div>
<div class="about">
<div class="about__ava ava">
<img class="ava__pic" src="{% static 'img/user.jpg' %}">
</div>
<div class="about__wrap">
<div class="about__content">
<p>Что такое «Рисовальный Лагерь»?</p>
<p>Это месяц фантазии, красок, карандашей и необычных заданий!</p>
<p>Любой ребёнок из любой точки мира в удобное время может порисовать с профессиональными преподавателями.</p>
<p>Мы поговорим о направлениях в живописи. О стилях и жанрах. Рассмотрим великие полотна,
познакомимся с художниками. И, конечно, создадим собственные работы в их стиле.</p>
<p>На наших занятиях нет понятий «правильно» и «неправильно». Есть только желание и вдохновение.</p>
<p>Мы зарядим вас и ваших детей творчеством! Присоединяйтесь!</p>
</div>
<div class="about__ceo">- Sasha Kru, CEO и основатель
<a href='#'>Lil.City</a>
</div>
<div style="text-align: center;"><a class="btn btn_light" href="{% url 'index' %}">ПОДРОБНЕЕ О LIL SCHOOL</a></div>
</div>
</div>
</div>
</div>

@ -0,0 +1,65 @@
{% load static %}
<div class="section">
<div class="section__center center">
<a id="gallery" name="gallery">
<div class="title title_center">Работы учеников</div>
</a>
<div class="text">
<p>Более 5 тысяч детей отучились с нами в Рисовальном Лагере прошлым летом. Присоединяйся и ты!</p>
</div>
<div class="gallery">
<div class="gallery__grid">
<a href="{% get_media_prefix %}instagram/results/0.jpg"
class="gallery__item gallery__item_lg">
<img class="gallery__pic" src="{% get_media_prefix %}instagram/results/0.jpg" onerror="this.style.display='none'">
</a>
<a href="{% get_media_prefix %}instagram/results/1.jpg"
class="gallery__item">
<img class="gallery__pic" src="{% get_media_prefix %}instagram/results/1.jpg" onerror="this.style.display='none'">
</a>
<a href="{% get_media_prefix %}instagram/results/2.jpg"
class="gallery__item">
<img class="gallery__pic" src="{% get_media_prefix %}instagram/results/2.jpg" onerror="this.style.display='none'">
</a>
<a href="{% get_media_prefix %}instagram/results/3.jpg"
class="gallery__item">
<img class="gallery__pic" src="{% get_media_prefix %}instagram/results/3.jpg" onerror="this.style.display='none'">
</a>
<a href="{% get_media_prefix %}instagram/results/4.jpg"
class="gallery__item">
<img class="gallery__pic" src="{% get_media_prefix %}instagram/results/4.jpg" onerror="this.style.display='none'">
</a>
<a href="{% get_media_prefix %}instagram/results/5.jpg"
class="gallery__item">
<img class="gallery__pic" src="{% get_media_prefix %}instagram/results/5.jpg" onerror="this.style.display='none'">
</a>
</div>
<div class="gallery__grid">
<a href="{% get_media_prefix %}instagram/results/6.jpg"
class="gallery__item">
<img class="gallery__pic" src="{% get_media_prefix %}instagram/results/6.jpg" onerror="this.style.display='none'">
</a>
<a href="{% get_media_prefix %}instagram/results/7.jpg"
class="gallery__item">
<img class="gallery__pic" src="{% get_media_prefix %}instagram/results/7.jpg" onerror="this.style.display='none'">
</a>
<a href="{% get_media_prefix %}instagram/results/8.jpg"
class="gallery__item">
<img class="gallery__pic" src="{% get_media_prefix %}instagram/results/8.jpg" onerror="this.style.display='none'">
</a>
<a href="{% get_media_prefix %}instagram/results/9.jpg"
class="gallery__item gallery__item_lg">
<img class="gallery__pic" src="{% get_media_prefix %}instagram/results/9.jpg" onerror="this.style.display='none'">
</a>
<a href="{% get_media_prefix %}instagram/results/10.jpg"
class="gallery__item">
<img class="gallery__pic" src="{% get_media_prefix %}instagram/results/10.jpg" onerror="this.style.display='none'">
</a>
<a href="{% get_media_prefix %}instagram/results/11.jpg"
class="gallery__item">
<img class="gallery__pic" src="{% get_media_prefix %}instagram/results/11.jpg" onerror="this.style.display='none'">
</a>
</div>
</div>
</div>
</div>

@ -0,0 +1,9 @@
{% load static %}
<a class="online" target="_blank" href="https://www.youtube.com/watch?v=PhZ8qQbIej0" style="background-image: url({% static 'img/video-1.jpg' %});">
<div class="online__center center">
<div class="online__type">ВИДЕОУРОКИ</div>
<div class="online__title">В 17.00 (по Мск) </div>
<div class="online__text text">Каждый день</div>
<div class="online__action"></div>
</div>
</a>

@ -0,0 +1,27 @@
{% load static %}
<div class="main main_default" style="background-image: url({% static 'img/bg-2.jpg' %});">
<div class="main__center center">
<div class="main__title">
<span class="main__bold">Рисовальный лагерь</span> — продолжение нашей онлайн-колы только летом.
Понедельник, среда и пятница ждем вас в 17:00 (мск). Уроки хранятся 7 дней.
</div>
<div class="main__actions">
<a
{% if not is_purchased_future %}
data-popup=".js-popup-buy"
data-is-camp="1"
{% endif %}
class="main__btn btn"
href="#"
>
{% if not is_purchased and not is_purchased_future %}Купить доступ за {{ drawing_camp_price }} руб./месяц{% endif %}
{% if is_purchased_future and not is_purchased %}ваша подписка начинается {{school_purchased_future.date_start}}{% endif %}
{% if is_purchased %}ваша подписка истекает {{ subscription_ends_humanize }}<br/>перейти к оплате{% endif %}
</a>
{% if not is_purchased and not is_purchased_future %}
<a class="main__btn btn btn_stroke-black" href="{% url 'gift-certificates' %}">Подарить другу</a>
{% endif %}
</div>
</div>
</div>

@ -0,0 +1,62 @@
{% load static %} {% load thumbnail %}
{% if next_schedule %}
<div class="section">
<div class="section__center center">
<div class="title title_center">
Следующий урок: {{ next_schedule.title }}
</div>
<div class="title title_sm title_center">
Начнется через {{ next_lesson_start }}
</div>
</div>
</div>
{% endif %}
{% include 'templates/blocks/messages.html' %}
<div class="section" id="schedule">
<div class="section__center center">
<div class="title title_center">Расписание</div>
<div class="casing">
<div class="casing__col">
<div class="casing__subscribe">
{% if is_purchased %}
<div class="casing__msg">Подписка истекает
<span class="bold">{{ subscription_ends }}</span>
</div>
{% else %}
<div class="casing__msg">Подписка
<span class="bold">истекла</span>
</div>
{% endif %}
{% if allow_prolong %}
{% include './prolong_btn.html' with pink=True %}
{% endif %}
</div>
</div>
<div class="casing__col">
<div class="casing__timing timing js-timing">
<div class="timing__week">
<div class="subtitle2">Новые уроки</div>
{% for school_schedule in school_schedules_sorted %}
{% if is_drawing_camp %}
{% include 'blocks/schedule_item.html' with school_schedule=school_schedule live_lesson=school_schedule.current_camp_lesson %}
{% else %}
{% include 'blocks/schedule_item.html' with school_schedule=school_schedule live_lesson=school_schedule.current_live_lesson %}
{% endif %}
{% endfor %}
{% if prev_live_lessons_exists %}
<div class="subtitle2">Прошедшие уроки</div>
{% for live_lesson in prev_live_lessons %}
{% if live_lesson.school_schedule and live_lesson.title %}
{% include 'blocks/schedule_item.html' with school_schedule=live_lesson.school_schedule live_lesson=live_lesson is_previous=True is_purchased=True %}
{% endif %}
{% endfor %}
{% endif %}
</div>
<div class="timing__week">
{% comment %} previous week schedules {% endcomment %}
</div>
</div>
</div>
</div>
</div>
</div>

@ -0,0 +1,16 @@
{% extends "templates/lilcity/index.html" %} {% load static %}
{% block title %}Рисовальный лагерь LilCity{% endblock title%}
{% block ogimage %}http://{{request.META.HTTP_HOST}}{% static 'img/og_main.jpg' %}{% endblock %}
{% block content %}
{% if not is_purchased and not prev_school_payments_exists %}
{% include "../drawing_camp/promo.html" %}
{% include "../blocks/schedule.html" %}
{% include "../drawing_camp/gallery.html" %}
{% include "../drawing_camp/about.html" %}
{% include "templates/blocks/game.html" %}
{% include "templates/blocks/partners.html" %}
{% else %}
{% include "../drawing_camp/schedule_purchased.html" %}
{% include "templates/blocks/partners.html" %}
{% endif %}
{% endblock %}

@ -1,7 +1,7 @@
{% extends "templates/lilcity/index.html" %}{% load static %} {% block content %}
<div class="main" style="background-image: url({% static 'img/bg-1.jpg' %});">
<div class="main__center center">
<div class="main__title">Уроки онлайн-школы LilCity</div>
<div class="main__title">Уроки {% if is_camp %}рисовального лагеря{% else %}онлайн-школы{% endif %} LilCity</div>
</div>
</div>
<div class="section">
@ -16,7 +16,8 @@
<use xlink:href="{% static 'img/sprite.svg' %}#icon-eye"></use>
</svg>
</a>
<a class="lessons__action" href="{% url 'school:lessons-edit' livelesson.id %}">
<a class="lessons__action" href="{% if livelesson.is_camp %}{% url 'school:camp-lessons-edit' livelesson.id %}
{% else %}{% url 'school:lessons-edit' livelesson.id %}{% endif %}">
<svg class="icon icon-edit">
<use xlink:href="{% static 'img/sprite.svg' %}#icon-edit"></use>
</svg>

@ -7,6 +7,7 @@
<div class="main__subtitle">
<!--Старт школы - 1 сентября-->
</div>
{% comment %}
<div class="main__actions">
<a
{% if not is_purchased_future %}
@ -24,6 +25,7 @@
<a class="main__btn btn btn_stroke-black" href="{% url 'gift-certificates' %}">Подарить другу</a>
{% endif %}
</div>
{% endcomment %}
<div class="main__school school school_main">
<div class="school__col">
<div class="school__preview">

@ -24,7 +24,11 @@
<div class="timing__week">
<div class="subtitle2">Новые уроки</div>
{% for school_schedule in school_schedules_sorted %}
{% include 'blocks/schedule_item.html' with school_schedule=school_schedule live_lesson=school_schedule.current_live_lesson %}
{% if is_drawing_camp %}
{% include 'blocks/schedule_item.html' with school_schedule=school_schedule live_lesson=school_schedule.current_camp_lesson %}
{% else %}
{% include 'blocks/schedule_item.html' with school_schedule=school_schedule live_lesson=school_schedule.current_live_lesson %}
{% endif %}
{% endfor %}
{% if prev_live_lessons_exists %}
<div class="subtitle2">Прошедшие уроки</div>

@ -3,15 +3,19 @@ from django.urls import path, re_path
from .views import (
LiveLessonsView, LiveLessonEditView,
LiveLessonsDetailView, SchoolView,
SchoolSchedulesPrintView,
)
SchoolSchedulesPrintView, DrawingCampView,
DrawingCampLessonsView)
urlpatterns = [
path('', SchoolView.as_view(), name='school'),
path('schedules/print', SchoolSchedulesPrintView.as_view(), name='school_schedules-print'),
path('lessons/', LiveLessonsView.as_view(), name='lessons'),
path('lessons/create', LiveLessonEditView.as_view(), name='lessons-create'),
path('lessons/<int:pk>/edit', LiveLessonEditView.as_view(), name='lessons-edit'),
path('lessons/<int:pk>/', LiveLessonsDetailView.as_view(), name='lesson-detail-id'),
re_path(r'(?P<lesson_date>\d+\-\d+\-\d+)', LiveLessonsDetailView.as_view(), name='lesson-detail'),
re_path(r'^(?P<lesson_date>\d+\-\d+\-\d+)', LiveLessonsDetailView.as_view(), name='lesson-detail'),
path('camp/', DrawingCampView.as_view(), name='drawing-camp'),
path('camp/lessons/', DrawingCampLessonsView.as_view(), name='camp-lessons'),
path('camp/lessons/<int:pk>/edit', LiveLessonEditView.as_view(), name='camp-lessons-edit', kwargs={'is_camp': True}),
re_path(r'^camp/(?P<lesson_date>\d+\-\d+\-\d+)', LiveLessonsDetailView.as_view(), name='camp-lesson-detail',
kwargs={'is_camp': True}),
]

@ -1,4 +1,6 @@
from datetime import datetime, timedelta, date
import arrow
from paymentwall import Pingback
from django.contrib.auth import get_user_model
@ -10,9 +12,10 @@ 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 django.conf import settings
from apps.course.models import Course
from apps.payment.models import SchoolPayment
from apps.payment.models import SchoolPayment, DrawingCampPayment
from .models import LiveLesson, SchoolSchedule
User = get_user_model()
@ -34,26 +37,54 @@ class LiveLessonsView(ListView):
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_start, date_end = SchoolPayment.get_date_range(date_start, days=17, is_camp=False)
date_range = Q(
date__range=[
date_start,
date_start + timedelta(days=17),
]
date__range=[date_start, date_end]
)
exist_dates = LiveLesson.objects.filter(date_range, is_camp=False).values_list('date', flat=True)
for i in range((date_end - date_start).days):
d = date_start + timedelta(days=i)
if d not in exist_dates:
try:
LiveLesson.objects.create(
date=date_start + timedelta(days=i),
is_camp=False,
)
except IntegrityError:
pass
queryset = LiveLesson.objects.filter(date_range)
if queryset.count() < 17:
for i in range(18):
return queryset
@method_decorator([login_required, is_admin_or_teacher], name='dispatch')
class DrawingCampLessonsView(ListView):
model = LiveLesson
template_name = 'school/livelessons_list.html'
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['is_camp'] = True
return context
def get_queryset(self):
date_start = (now() - timedelta(days=7)).date()
date_start, date_end = DrawingCampPayment.get_date_range(date_start, days=23, is_camp=True)
date_range = Q(
date__range=[date_start, date_end]
)
exist_dates = LiveLesson.objects.filter(date_range, is_camp=True).values_list('date', flat=True)
for i in range((date_end - date_start).days):
d = date_start + timedelta(days=i)
if d.isoweekday() in DrawingCampPayment.WEEKDAYS and d not in exist_dates:
try:
LiveLesson.objects.create(
date=date_start + timedelta(days=i),
is_camp=True,
)
except IntegrityError:
pass
queryset = LiveLesson.objects.filter(date_range)
queryset = LiveLesson.objects.filter(date_range)
return queryset
@ -61,16 +92,20 @@ class LiveLessonsDetailView(DetailView):
model = LiveLesson
template_name = 'school/livelesson_detail.html'
def get(self, request, pk=None, lesson_date=None):
def get(self, request, pk=None, lesson_date=None, is_camp=False):
if pk:
self.object = self.get_object()
if lesson_date:
try:
self.object = LiveLesson.objects.get(date=datetime.strptime(lesson_date, '%d-%m-%y'))
self.object = LiveLesson.objects.get(date=datetime.strptime(lesson_date, '%d-%m-%y'), is_camp=is_camp)
except Exception:
raise Http404()
if request.user.is_authenticated:
is_purchased = SchoolPayment.objects.filter(
if self.object.is_camp:
is_purchased = DrawingCampPayment.objects.all()
else:
is_purchased = SchoolPayment.objects.filter(weekdays__contains=[self.object.date.weekday() + 1],)
is_purchased = is_purchased.filter(
user=request.user,
date_start__lte=now(),
date_end__gte=now() - timedelta(days=7),
@ -79,7 +114,6 @@ class LiveLessonsDetailView(DetailView):
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
@ -94,20 +128,21 @@ class LiveLessonsDetailView(DetailView):
class LiveLessonEditView(TemplateView):
template_name = 'course/course_edit.html'
def get(self, request, pk=None):
def get(self, request, pk=None, is_camp=False):
if pk:
self.object = get_object_or_404(LiveLesson, pk=pk)
self.object = get_object_or_404(LiveLesson, pk=pk, is_camp=is_camp)
else:
try:
self.object = LiveLesson.objects.get(date=now().date())
except LiveLesson.DoesNotExist:
self.object = LiveLesson.objects.create()
self.object = LiveLesson.objects.create(is_camp=is_camp)
return super().get(request)
def get_context_data(self):
context = super().get_context_data()
context['object'] = self.object
context['live'] = 'true'
context['is_camp'] = 'true' if self.object.is_camp else 'false'
return context
@ -204,12 +239,12 @@ class SchoolView(TemplateView):
'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,
'is_purchased_future': school_purchased_future and school_purchased_future.exists(),
'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,
'school_purchased_future': school_purchased_future and school_purchased_future.last(),
'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,
@ -226,3 +261,117 @@ class SchoolSchedulesPrintView(TemplateView):
context = super().get_context_data()
context['school_schedules'] = SchoolSchedule.objects.all()
return context
class DrawingCampView(TemplateView):
template_name = 'school/drawing_camp.html'
def get_context_data(self):
context = super().get_context_data()
date_now = now().date()
now_time = now()
online = False
next_schedule = None
if now_time.isoweekday() in DrawingCampPayment.WEEKDAYS:
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_camp_lesson
)
if school_schedule.current_camp_lesson and school_schedule.start_at > now_time.time():
next_schedule = school_schedule
next_lesson_start = next_schedule.start_at_humanize
if not next_schedule:
next_camp_lesson = LiveLesson.objects.filter(date__gt=date_now, is_camp=True).first()
if next_camp_lesson:
next_schedule = next_camp_lesson.school_schedule
next_lesson_start = arrow.get(datetime.combine(next_camp_lesson.date, next_schedule.start_at),
settings.TIME_ZONE).humanize(locale='ru')
school_schedules = SchoolSchedule.objects.filter(weekday__in=DrawingCampPayment.WEEKDAYS)
try:
school_schedules_sorted = sorted(school_schedules,
key=lambda ss: ss.current_camp_lesson and ss.current_camp_lesson.date)
except Exception:
school_schedules_sorted = school_schedules
prev_live_lessons = []
prev_live_lessons_exists = False
subscription_ends = None
camp_payment_exists = False
camp_purchased_future = False
prev_camp_payments = None
prev_range = [date_now - timedelta(days=7), date_now - timedelta(days=1)]
if self.request.user.is_authenticated:
camp_payment = DrawingCampPayment.objects.filter(
user=self.request.user,
status__in=DrawingCampPayment.PW_PAID_STATUSES,
date_start__lte=date_now,
date_end__gte=date_now
)
camp_payment_exists = camp_payment.exists()
camp_purchased_future = DrawingCampPayment.objects.filter(
user=self.request.user,
status__in=DrawingCampPayment.PW_PAID_STATUSES,
date_start__gt=date_now,
date_end__gt=date_now
)
if camp_purchased_future.exists():
subscription_ends = camp_purchased_future.latest('date_end').date_end
elif camp_payment_exists:
subscription_ends = camp_payment.latest('date_end').date_end
prev_camp_payments = DrawingCampPayment.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,
],
)
# берем все подписки, которые были в периоде
for sp in prev_camp_payments:
# берем все уроки в оплаченном промежутке
date_range = [max(sp.date_start, prev_range[0]), min(sp.date_end, prev_range[1])]
prev_live_lessons += list(LiveLesson.objects.filter(
date__range=date_range,
deactivated_at__isnull=True,
is_camp=True,
).exclude(title='').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())
context.update({
'next_schedule': next_schedule,
'next_lesson_start': next_lesson_start,
'is_drawing_camp': True,
'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': camp_payment_exists,
'is_purchased_future': camp_purchased_future and camp_purchased_future.exists(),
'drawing_camp_price': DrawingCampPayment.MONTH_PRICE,
'school_schedules_sorted': school_schedules_sorted,
'school_schedules': school_schedules,
'school_schedules_purchased': DrawingCampPayment.WEEKDAYS if camp_payment_exists else [],
'school_purchased_future': camp_purchased_future and camp_purchased_future.last(),
'prev_school_payments_exists': prev_camp_payments and prev_camp_payments.exists(),
'subscription_ends': subscription_ends,
'prolong_date_start': subscription_ends + timedelta(days=1) if subscription_ends else None,
})
return context

@ -11,7 +11,8 @@
<div class="footer__title">Продукты</div>
<nav class="footer__nav">
<div>
<a class="footer__link" href="{% url 'school:school' %}">Онлайн-школа</a>
<!-- <a class="footer__link" href="{% url 'school:school' %}">Онлайн-школа</a> -->
<a class="footer__link" href="{% url 'school:drawing-camp' %}">Рисовальный лагерь</a>
<a class="footer__link" href="{% url 'courses' %}">Видео-курсы</a>
<a class="footer__link" href="https://blog.lil.school">Блог</a>
</div>

@ -25,12 +25,20 @@
</form>
</div>
<nav class="header__nav">
<div class="header__group">
<!-- <div class="header__group">
<a class="header__section {% active_link 'school:school' %}" href="{% url 'school:school' %}">
ОНЛАЙН-ШКОЛА {% if online or livelesson.is_online %}
<div class="header__dot"></div>
{% endif %}
</a>
</div> -->
<div class="header__group">
<a class="header__section {% active_link 'school:drawing-camp' %}" href="{% url 'school:drawing-camp' %}">
РИСОВАЛЬНЫЙ ЛАГЕРЬ {% if online or livelesson.is_online %}
<div class="header__dot"></div>
{% endif %}
</a>
</div>
<div class="header__group">
<a class="header__section header__section_sub js-header-section {% active_link 'courses' %}" href="{% url 'courses' %}">ВИДЕО-КУРСЫ</a>

@ -44,12 +44,12 @@
{% if school_schedule.weekday in school_schedules_purchased %}
Куплено
{% else %}
{% if school_schedule.trial_lesson %}
{% if school_schedule.trial_lesson and not is_drawing_camp %}
<a class="js-video-modal" data-video-url="{{ school_schedule.trial_lesson }}" data-trial-lesson="1" href="">Пробный урок</a>
{% endif %}
{% endif %}
</span>
<span class="switch__cell">{{school_schedule.month_price}}р в мес.</span>
<span class="switch__cell">{% if not is_drawing_camp %}{{school_schedule.month_price}}р в мес.{% endif %}</span>
</span>
</label>
{% endfor %}
@ -91,7 +91,8 @@
</div>
</div>
<div class="buy__foot">
<a class="buy__btn btn btn_md but_btn_popup" data-link="{% url 'school-checkout' %}">ПЕРЕЙТИ К ОПЛАТЕ</a>
<a class="buy__btn btn btn_md but_btn_popup"
data-link="{% if is_drawing_camp %}{% url 'camp-checkout' %}{% else %}{% url 'school-checkout' %}{% endif %}">ПЕРЕЙТИ К ОПЛАТЕ</a>
</div>
</div>
</div>

@ -11,6 +11,26 @@
<div class="main__title">
<span class="main__bold">Lil School</span> — первая образовательная онлайн-платформа креативного мышления для детей! 5+
</div>
<div class="main__subtitle">
Приглашаем вас присоединиться к рисовальному лагерю
</div>
<div class="main__actions">
{% if not is_purchased and not is_purchased_future %}
<a
data-popup=".js-popup-buy"
class="main__btn btn"
data-is-camp="1"
href="#"
>
купить доступ от {{ camp_price }} руб./месяц
</a>
<a class="main__btn btn btn_stroke-black" href="{% url 'gift-certificates' %}">Подарить другу</a>
{% else %}
<a class="main__btn btn" href="{% url 'school:drawing-camp' %}">Подробнее</a>
{% endif %}
</div>
{% comment %}
{% if user.is_authenticated and online %}
<div class="main__content">
Сейчас идёт прямой эфир урока «{{ school_schedule.title }}, {{ school_schedule.current_live_lesson.title }}»
@ -22,7 +42,7 @@
data-day="{{ school_schedule.weekday }}"
href='#'
{% else %}
href="{% url 'school:school' %}"
href="{% url 'school:drawing-camp' %}"
{% endif %}
class="main__btn btn"
>{% if not school_schedule.weekday in school_schedules_purchased %}Получить доступ{% else %}Смотреть урок{% endif %}</a>
@ -45,7 +65,7 @@
data-day="{{ school_schedule.weekday }}"
href='#'
{% else %}
href="{% url 'school:school' %}"
href="{% url 'school:drawing-camp' %}"
{% endif %}
class="main__btn btn"
>{% if not school_schedule.weekday in school_schedules_purchased %}Получить доступ{% else %}Смотреть урок{% endif %}</a>
@ -73,5 +93,6 @@
{% endif %}
</div>
{% endif %}
{% endcomment %}
</div>
</div>

@ -33,6 +33,9 @@
<a class="header__link" href="{% url 'school:lessons' %}">
<div class="header__title">УРОКИ ШКОЛЫ</div>
</a>
<a class="header__link" href="{% url 'school:camp-lessons' %}">
<div class="header__title">УРОКИ ЛАГЕРЯ</div>
</a>
{% endif %}
{% endif %}
<a class="header__link" href="{% url 'user-profile' %}">

@ -35,7 +35,7 @@ from apps.payment.views import (
CourseBuySuccessView, CourseBuyView,
PaymentwallCallbackView, SchoolBuySuccessView,
SchoolBuyView, GiftCertificatesView, GiftCertificateBuyView,
GiftCertificateBuySuccessView, GiftCertificateGetView)
GiftCertificateBuySuccessView, GiftCertificateGetView, DrawingCampBuyView)
from .views import AboutView, IndexView, SchoolSchedulesView, LinksView
@ -56,7 +56,8 @@ urlpatterns = [
path('course/<int:pk>/checkout', CourseBuyView.as_view(), name='course-checkout'),
path('course/<int:pk>/edit', CourseEditView.as_view(), name='course_edit'),
path('course/<int:pk>/edit/lessons', CourseEditView.as_view(), name='course_edit_lessons'),
path('course/<int:pk>/lessons', CourseView.as_view(template_name='course/course_only_lessons.html', only_lessons=True), name='course-only-lessons'),
path('course/<int:pk>/lessons', CourseView.as_view(template_name='course/course_only_lessons.html', only_lessons=True),
name='course-only-lessons'),
path('course/<int:course_id>/like', likes, name='likes'),
path('course/<int:course_id>/comment', coursecomment, name='coursecomment'),
path('lesson/<int:pk>/', LessonView.as_view(), name='lesson'),
@ -65,8 +66,11 @@ urlpatterns = [
path('paymentwall/pingback', PaymentwallCallbackView.as_view(), name='payment-ping-second'),
path('payments/course/<int:pk>/success', CourseBuySuccessView.as_view(), name='course_payment_success'),
path('payments/school/success', SchoolBuySuccessView.as_view(), name='payment-success'),
path('payments/school/camp/success', SchoolBuySuccessView.as_view(), name='camp-payment-success',
kwargs={'is_camp': True}),
path('payments/error', TemplateView.as_view(template_name='payment/payment_error.html'), name='payment-error'),
path('school/checkout', SchoolBuyView.as_view(), name='school-checkout'),
path('school/camp/checkout', DrawingCampBuyView.as_view(), name='camp-checkout'),
path('search/', SearchView.as_view(), name='search'),
path('user/profile/', ProfileView.as_view(), name='user-profile'),
path('user/profile/edit', ProfileEditView.as_view(), name='user-edit-profile'),

@ -10,7 +10,7 @@ from paymentwall.pingback import Pingback
from apps.course.models import Course
from apps.school.models import SchoolSchedule
from apps.payment.models import SchoolPayment, UserGiftCertificate, Payment
from apps.payment.models import SchoolPayment, UserGiftCertificate, Payment, DrawingCampPayment
User = get_user_model()
@ -65,7 +65,16 @@ class IndexView(TemplateView):
joined_weekdays=Func(F('weekdays'), function='unnest',)
).values_list('joined_weekdays', flat=True).distinct()
camp_payment = DrawingCampPayment.objects.filter(
user=self.request.user,
status__in=DrawingCampPayment.PW_PAID_STATUSES,
date_start__lte=date_now,
date_end__gte=date_now
)
camp_payment_exists = camp_payment.exists()
else:
camp_payment_exists = False
school_payment_exists = False
school_schedules_purchased = []
@ -90,6 +99,7 @@ class IndexView(TemplateView):
shuffle(review_images)
context.update({
'is_drawing_camp': True,
'review_images': review_images,
'gift_certificate': user_gift_certificate.gift_certificate if user_gift_certificate else None,
'user_gift_certificate': user_gift_certificate,
@ -100,14 +110,17 @@ class IndexView(TemplateView):
'online_coming_soon': online_coming_soon,
'school_schedule': school_schedule,
'course_items': Course.shuffle(Course.objects.filter(status=Course.PUBLISHED)[:3]),
'is_purchased': school_payment_exists,
'is_purchased': camp_payment_exists, # school_payment_exists,
'camp_price': DrawingCampPayment.MONTH_PRICE,
'min_school_price': SchoolSchedule.objects.aggregate(Min('month_price'))['month_price__min'],
'school_schedules': SchoolSchedule.objects.all(),
'school_schedules_purchased': set(school_schedules_purchased),
'school_schedules': SchoolSchedule.objects.filter(weekday__in=DrawingCampPayment.WEEKDAYS),
'school_schedules_purchased': DrawingCampPayment.WEEKDAYS if camp_payment_exists else [], # set(school_schedules_purchased),
'teachers': User.objects.filter(role=User.TEACHER_ROLE, show_in_mainpage=True),
'works_count': Payment.objects.filter(status__in=Payment.PW_PAID_STATUSES).count() * 7,
'subscription_ends': school_payment.filter(add_days=False).first().date_end if school_payment_exists else None,
'subscription_ends_humanize': school_payment.filter(add_days=False).first().date_end_humanize if school_payment_exists else None,
# 'subscription_ends': school_payment.filter(add_days=False).first().date_end if school_payment_exists else None,
# 'subscription_ends_humanize': school_payment.filter(add_days=False).first().date_end_humanize if school_payment_exists else None,
'subscription_ends': camp_payment.latest('date_end').date_end if camp_payment_exists else None,
'subscription_ends_humanize': camp_payment.latest('date_end').date_end_humanize if camp_payment_exists else None,
'school_purchased_future': False,
'is_purchased_future': False,

@ -259,7 +259,7 @@
export default {
name: "course-redactor",
props: ["authorName", "authorPicture", "accessToken", "courseId", "live"],
props: ["authorName", "authorPicture", "accessToken", "courseId", "live", "camp"],
data() {
return {
disabledDates: {
@ -670,7 +670,7 @@
publishButton.attr('disabled', 'disabled');
if(this.live) {
window.location = '/school/lessons';
window.location = this.camp ? '/school/camp/lessons' : '/school/lessons';
} else {
api.publishCourse(this.course, this.accessToken)
.then((response) => {
@ -762,7 +762,7 @@
this.courseSaving = true;
this.changeSavingStatus();
const courseObject = this.course;
const courseObject = Object.assign({}, this.course);
courseObject.slug = this.getSlug(courseObject.slug);
api.saveCourse(courseObject, this.accessToken)
.then((response) => {

@ -171,6 +171,7 @@ $(document).ready(function () {
if(data === '.js-popup-buy') {
popup.data('date-start', $this.data('date-start') || '');
popup.data('day', $this.data('day') || '');
popup.data('is-camp', $this.data('is-camp') || '');
$('[data-day]').prop('checked', false);
if(! window.LIL_STORE.user.id) {
@ -185,7 +186,12 @@ $(document).ready(function () {
});
}
if ($this.data('prolong')) {
if ($this.data('is-camp')) {
$('[data-day]').each(function(){
$(this).prop('checked', true).prop('disabled', true);
});
}
else if ($this.data('prolong')) {
$('[data-day][data-purchased]').each(function(){
$(this).prop('checked', true).prop('disabled', false);
});
@ -410,7 +416,8 @@ $(document).ready(function () {
if(weekdays.length){
$order.addClass('order--loading');
$orderPrice.html('');
api.getPaymentAmount({ user: window.LIL_STORE.user.id, weekdays: weekdays, date_start: dateStart})
api.getPaymentAmount({ user: window.LIL_STORE.user.id, weekdays: weekdays, date_start: dateStart,
is_camp: popup.data('is-camp')})
.then(response => {
$order.removeClass('order--loading');
var text = '';

Loading…
Cancel
Save