Уведомление об окончании доступа к курсу

remotes/origin/feature/course-access-expire-notification
gzbender 6 years ago
parent 49a4247518
commit b36ad1f28a
  1. 2
      apps/notification/tasks.py
  2. 17
      apps/notification/templates/notification/email/buy_email.html
  3. 2
      apps/payment/templates/payment/pay.html
  4. 103
      apps/payment/views.py

@ -239,7 +239,7 @@ def send_camp_certificates(email=None, dry_run=False, certificate_number=None):
def send_course_access_expire_email(days=None): def send_course_access_expire_email(days=None):
if days is None: if days is None:
days = 30 days = 30
payments = CoursePayment.objects.paid().filter(access_expire=now() + timedelta(days - 1), created_at__lte=now() - timedelta(10)) payments = CoursePayment.objects.paid().filter(access_expire__lte=now() + timedelta(days - 1), created_at__lte=now() - timedelta(10))
for payment in payments: for payment in payments:
cn, created = CourseNotification.objects.get_or_create(course=payment.course, user=payment.user) cn, created = CourseNotification.objects.get_or_create(course=payment.course, user=payment.user)
if not created and cn.access_expire_last_email and cn.access_expire_last_email.date() >= now().date() - timedelta(days): if not created and cn.access_expire_last_email and cn.access_expire_last_email.date() >= now().date() - timedelta(days):

@ -1,24 +1,25 @@
{% extends "notification/email/_base.html" %} {% extends "notification/email/_base.html" %}
{% load rupluralize from plural %} {% load rupluralize from plural %}
{% load settings %}
{% block content %} {% block content %}
{% if product_type == 'course' %} {% if product_type == 'course' %}
<p>Добрый день, {{ username }}!</p> <p>Добрый день, {{ username }}!</p>
<p>Вы приобрели видеокурс «{{ course_title }}». Спасибо за покупку!</p> <p>Вы приобрели видеокурс «{{ course_title }}». Спасибо за покупку!</p>
<p>Обратите внимание, что доступ к курсу действует {{ access_duration | rupluralize:'день,дня,дней' }}. Этого должно хватить, чтобы пройти его. <p>Обратите внимание, что доступ к курсу действует {{ access_duration | rupluralize:'день,дня,дней' }}. Этого должно хватить, чтобы пройти его.
Если вы не успеете, то по окончании этого срока система автоматически предложит вам продлить доступ к курсу за 50% от его стоимости./p> Если вы не успеете, то по окончании этого срока система автоматически предложит вам продлить доступ к курсу за 50% от его стоимости.</p>
<p>Найти курс можно в вашем личном кабинете на платформе.</p> <p>Найти курс можно в вашем личном кабинете на платформе.</p>
<p><a href="https://{{ settings.MAIN_HOST }}{{ url }}"> <p><a href="https://{% setting 'MAIN_HOST' %}{{ url }}">
https://{{ settings.MAIN_HOST }}{{ url }}</a></p> https://{% setting 'MAIN_HOST' %}{{ url }}</a></p>
<p>Все ваши покупки будут храниться там в рамках срока доступа к курсу.</p> <p>Все ваши покупки будут храниться там в рамках срока доступа к курсу.</p>
{% endif %} {% endif %}
{% if product_type == 'school' %} {% if product_type == 'school' %}
<p>Добрый день! Спасибо за покупку знаний в «Lil School»!</p> <p>Добрый день! Спасибо за покупку знаний в «Lil School»!</p>
<p>Где искать уроки?</p> <p>Где искать уроки?</p>
<p>После оплаты уроки появятся в вашем личном кабинете на платформе.</p> <p>После оплаты уроки появятся в вашем личном кабинете на платформе.</p>
<p><a href="https://{{ settings.MAIN_HOST }}{% url 'school:school' %}"> <p><a href="https://{% setting 'MAIN_HOST' %}{% url 'school:school' %}">
https://{{ settings.MAIN_HOST }}{% url 'school:school' %}</a></p> https://{% setting 'MAIN_HOST' %}{% url 'school:school' %}</a></p>
<p>В онлайн-школе урок хранится неделю. Ровно до следующего урока.</p> <p>В онлайн-школе урок хранится неделю. Ровно до следующего урока. Либо месяц при покупке подписки на год.</p>
{% endif %} {% endif %}
{% if product_type == 'drawing_camp' %} {% if product_type == 'drawing_camp' %}
{% if date_start.month == 7 and date_start.day == 1 and date_end.day == 31 %} {% if date_start.month == 7 and date_start.day == 1 and date_end.day == 31 %}
@ -78,8 +79,8 @@
Обязательно делитесь своими впечатлениями и работами, отмечая их хэштегом #lil_summer. Спасибо, что вы с нами! Обязательно делитесь своими впечатлениями и работами, отмечая их хэштегом #lil_summer. Спасибо, что вы с нами!
</p> </p>
{% else %} {% else %}
<p>Рисовальный лагерь ждет вас по ссылке <a href="https://{{ settings.MAIN_HOST }}{% url 'school:drawing-camp' %}"> <p>Рисовальный лагерь ждет вас по ссылке <a href="https://{% setting 'MAIN_HOST' %}{% url 'school:drawing-camp' %}">
https://{{ settings.MAIN_HOST }}{% url 'school:drawing-camp' %}</a></p> https://{% setting 'MAIN_HOST' %}{% url 'school:drawing-camp' %}</a></p>
{% endif %} {% endif %}
{% endif %} {% endif %}

@ -12,7 +12,7 @@
{% else %} {% else %}
<div class="text2"><p>Для оплаты части стоимости вы можете использовать бонусы</p></div> <div class="text2"><p>Для оплаты части стоимости вы можете использовать бонусы</p></div>
<label id="use-bonuses-checkbox" class="switch" style="margin-bottom: 20px"> <label id="use-bonuses-checkbox" class="switch" style="margin-bottom: 20px">
<input class="switch__input" data-url="{{ request.get_full_path }}" value="true" type="checkbox"> <input class="switch__input" data-url="{{ bonuses_url }}" value="true" type="checkbox">
<span class="switch__content">Использовать {{ request.user.bonus|rupluralize:'бонус,бонуса,бонусов' }}</span> <span class="switch__content">Использовать {{ request.user.bonus|rupluralize:'бонус,бонуса,бонусов' }}</span>
</label> </label>
{% endif %} {% endif %}

@ -4,7 +4,7 @@ import json
import logging import logging
from datetime import timedelta from datetime import timedelta
from urllib.parse import urlsplit from urllib.parse import urljoin
import datetime import datetime
@ -41,6 +41,7 @@ class BuyMixin(object):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
roistat_visit = request.COOKIES.get('roistat_visit', None) roistat_visit = request.COOKIES.get('roistat_visit', None)
use_bonuses = request.GET.get('use_bonuses') use_bonuses = request.GET.get('use_bonuses')
payment_id = request.GET.get('payment_id')
product_name = '' product_name = ''
context = self.get_context_data(**kwargs) context = self.get_context_data(**kwargs)
payment = None payment = None
@ -48,10 +49,13 @@ class BuyMixin(object):
if self.product_type == 'gift_certificate': if self.product_type == 'gift_certificate':
gift_certificate = get_object_or_404(GiftCertificate, pk=kwargs.get('pk')) gift_certificate = get_object_or_404(GiftCertificate, pk=kwargs.get('pk'))
payment = GiftCertificatePayment.objects.create( if payment_id:
user=request.user, payment = GiftCertificatePayment.objects.get(pk=payment_id)
gift_certificate=gift_certificate, else:
roistat_visit=roistat_visit, ) payment = GiftCertificatePayment.objects.create(
user=request.user,
gift_certificate=gift_certificate,
roistat_visit=roistat_visit, )
success_url = reverse('gift-certificate-payment-success', args=[payment.id]) success_url = reverse('gift-certificate-payment-success', args=[payment.id])
product_name = 'Подарочный сертификат' product_name = 'Подарочный сертификат'
@ -82,7 +86,6 @@ class BuyMixin(object):
if self.product_type == 'school': if self.product_type == 'school':
date_start = request.GET.get('date_start') date_start = request.GET.get('date_start')
duration = request.GET.get('duration') duration = request.GET.get('duration')
payment_id = request.GET.get('payment_id')
package = get_object_or_404(Package, duration=duration) package = get_object_or_404(Package, duration=duration)
date_start = date_start and datetime.datetime.strptime(date_start, '%Y-%m-%d').date() or now().date() date_start = date_start and datetime.datetime.strptime(date_start, '%Y-%m-%d').date() or now().date()
@ -92,7 +95,7 @@ class BuyMixin(object):
if prev_payment and prev_payment.date_end > date_start: if prev_payment and prev_payment.date_end > date_start:
date_start = prev_payment.date_end + timedelta(1) date_start = prev_payment.date_end + timedelta(1)
if payment_id: if payment_id:
payment = get_object_or_404(SchoolPayment, id=payment_id) payment = SchoolPayment.objects.get(pk=payment_id)
else: else:
amount_data = SchoolPayment.calc_amount(package=package, user=request.user, date_start=date_start) amount_data = SchoolPayment.calc_amount(package=package, user=request.user, date_start=date_start)
payment = SchoolPayment.objects.create( payment = SchoolPayment.objects.create(
@ -103,11 +106,6 @@ class BuyMixin(object):
date_end=amount_data.get('date_end'), date_end=amount_data.get('date_end'),
package=package, package=package,
) )
if payment_id and payment.bonus and not use_bonuses:
bonus = payment.bonus
payment.amount += payment.bonus
payment.bonus = None
bonus.delete()
success_url = '%s?duration=%s' % (reverse('payment-success'), duration) success_url = '%s?duration=%s' % (reverse('payment-success'), duration)
product_name = 'Подписка' product_name = 'Подписка'
context['school'] = True context['school'] = True
@ -116,28 +114,33 @@ class BuyMixin(object):
date_start = request.GET.get('date_start') 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_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) date_start, date_end = Payment.get_date_range(date_start, months=1, is_camp=True)
prev_payment = DrawingCampPayment.objects.filter( prev_payment = DrawingCampPayment.objects.paid().filter(
user=request.user, user=request.user,
date_start__lte=date_start, date_start__lte=date_start,
date_end__gte=date_start, date_end__gte=date_start,
status__in=[
Pingback.PINGBACK_TYPE_REGULAR,
Pingback.PINGBACK_TYPE_GOODWILL,
Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,
],
).exists() ).exists()
if prev_payment: if prev_payment:
return HttpResponse(status=403) return HttpResponse(status=403)
payment = DrawingCampPayment.objects.create( if payment_id:
user=request.user, payment = DrawingCampPayment.objects.get(pk=payment_id)
roistat_visit=roistat_visit, else:
date_start=date_start, payment = DrawingCampPayment.objects.create(
date_end=date_end, user=request.user,
) roistat_visit=roistat_visit,
date_start=date_start,
date_end=date_end,
)
success_url = reverse('camp-payment-success') success_url = reverse('camp-payment-success')
product_name = 'Подписка' product_name = 'Подписка'
context['camp'] = True context['camp'] = True
if payment_id and payment.bonus and not use_bonuses:
bonus = payment.bonus
payment.amount -= payment.bonus.amount
payment.bonus = None
payment.save()
bonus.delete()
if use_bonuses and request.user.bonus: if use_bonuses and request.user.bonus:
if request.user.bonus >= payment.amount: if request.user.bonus >= payment.amount:
bonus = UserBonus.objects.create(amount=-payment.amount, user=request.user, payment=payment) bonus = UserBonus.objects.create(amount=-payment.amount, user=request.user, payment=payment)
@ -179,21 +182,22 @@ class BuyMixin(object):
if request.user_agent.is_mobile: if request.user_agent.is_mobile:
attrs['width'] = '100%' attrs['width'] = '100%'
attrs['height'] = '600' attrs['height'] = '600'
context['widget'] = widget.get_html_code(attrs) query = request.GET.copy()
if 'use_bonuses' in query:
query.pop('use_bonuses')
query['payment_id'] = payment.id
context.update({
'widget': widget.get_html_code(attrs),
'payment': payment,
'bonuses_url': '?'.join([request.path, query.urlencode()]),
})
return self.render_to_response(context) return self.render_to_response(context)
def after_buy(self, payment): def after_buy(self, payment):
product_type_name = None product_type_name = None
if isinstance(payment, CoursePayment):
product_type_name == 'course'
elif isinstance(payment, SchoolPayment):
product_type_name == 'school'
elif isinstance(payment, DrawingCampPayment):
product_type_name == 'drawing_camp'
elif isinstance(payment, GiftCertificatePayment):
product_type_name == 'gift_certificate'
if product_type_name == 'course': if isinstance(payment, CoursePayment):
product_type_name = 'course'
properties = { properties = {
'payment_id': payment.id, 'payment_id': payment.id,
'amount': payment.amount, 'amount': payment.amount,
@ -202,7 +206,12 @@ class BuyMixin(object):
'created_at': payment.created_at, 'created_at': payment.created_at,
'update_at': payment.update_at, 'update_at': payment.update_at,
} }
elif product_type_name == 'school': send_email.delay('Спасибо за покупку!', payment.user.email, 'notification/email/buy_email.html',
product_type=product_type_name, url=payment.course.url,
username=payment.user.get_full_name(), course_title=payment.course.title,
access_duration=payment.access_duration)
elif isinstance(payment, SchoolPayment):
product_type_name = 'school'
properties = { properties = {
'payment_id': payment.id, 'payment_id': payment.id,
'amount': payment.amount, 'amount': payment.amount,
@ -214,7 +223,10 @@ class BuyMixin(object):
'created_at': payment.created_at, 'created_at': payment.created_at,
'update_at': payment.update_at, 'update_at': payment.update_at,
} }
elif product_type_name == 'drawing_camp': send_email.delay('Спасибо за покупку!', payment.user.email, 'notification/email/buy_email.html',
product_type=product_type_name, date_start=payment.date_start, date_end=payment.date_end)
elif isinstance(payment, DrawingCampPayment):
product_type_name = 'drawing_camp'
properties = { properties = {
'payment_id': payment.id, 'payment_id': payment.id,
'amount': payment.amount, 'amount': payment.amount,
@ -224,7 +236,10 @@ class BuyMixin(object):
'created_at': payment.created_at, 'created_at': payment.created_at,
'update_at': payment.update_at, 'update_at': payment.update_at,
} }
elif product_type_name == 'gift_certificate': send_email.delay('Спасибо за покупку!', payment.user.email, 'notification/email/buy_email.html',
product_type=product_type_name)
elif isinstance(payment, GiftCertificatePayment):
product_type_name = 'gift_certificate'
properties = { properties = {
'payment_id': payment.id, 'payment_id': payment.id,
'amount': payment.amount, 'amount': payment.amount,
@ -233,6 +248,8 @@ class BuyMixin(object):
'created_at': payment.created_at, 'created_at': payment.created_at,
'update_at': payment.update_at, 'update_at': payment.update_at,
} }
send_email.delay('Спасибо за покупку!', payment.user.email, 'notification/email/buy_email.html',
product_type=product_type_name)
product_payment_to_mixpanel.delay( product_payment_to_mixpanel.delay(
payment.user.id, payment.user.id,
@ -252,18 +269,6 @@ class BuyMixin(object):
payment.roistat_visit, payment.roistat_visit,
) )
if product_type_name == 'course':
send_email.delay('Спасибо за покупку!', payment.user.email, 'notification/email/buy_email.html',
product_type=product_type_name, url=payment.course.url,
username=payment.user.get_full_name(), course_title=payment.course.title,
access_duration=payment.access_duration)
elif product_type_name != 'school':
send_email.delay('Спасибо за покупку!', payment.user.email, 'notification/email/buy_email.html',
product_type=product_type_name)
elif product_type_name != 'drawing_camp':
send_email.delay('Спасибо за покупку!', payment.user.email, 'notification/email/buy_email.html',
product_type=product_type_name, date_start=payment.date_start, date_end=payment.date_end)
author_balance = getattr(payment, 'author_balance', None) author_balance = getattr(payment, 'author_balance', None)
if author_balance and author_balance.type == AuthorBalance.IN: if author_balance and author_balance.type == AuthorBalance.IN:
if payment.is_deliverable(): if payment.is_deliverable():

Loading…
Cancel
Save