Вычисление скидок в фронтенд части

remotes/origin/feature/discounts-12-9-19
Ivan Kazionov 6 years ago
parent db0bbdf21f
commit 0cd01c08a8
  1. 8
      apps/course/templates/course/_items.html
  2. 5
      apps/course/templates/course/course.html
  3. 31
      apps/course/views.py
  4. 30
      apps/payment/models.py
  5. 0
      apps/payment/templatetags/__init__.py
  6. 11
      apps/payment/templatetags/discounts_tags.py
  7. 185
      apps/payment/tests/tests_models.py
  8. 12
      project/templates/lilcity/packages.html
  9. 18
      project/views.py

@ -1,5 +1,4 @@
{% load thumbnail %} {% load thumbnail static discounts_tags %}
{% load static %}
{% load data_liked from data_liked %} {% load data_liked from data_liked %}
<div <div
@ -49,9 +48,10 @@
<a class="courses__theme theme {{ theme_color }}" <a class="courses__theme theme {{ theme_color }}"
href="{% url 'courses' %}?category={{ course.category.id }}">{{ course.category | upper }}</a> href="{% url 'courses' %}?category={{ course.category.id }}">{{ course.category | upper }}</a>
{% if not course.is_free %} {% if not course.is_free %}
{% if course.buy_again_price %} {% get_price_for_item course.pk course.price discounts_per_course all_courses_discount as price_with_discount %}
{% if course.price > price_with_discount %}
<div class="courses__old-price mobile-hide"><s>{{ course.price|floatformat:"-2" }}₽</s></div> <div class="courses__old-price mobile-hide"><s>{{ course.price|floatformat:"-2" }}₽</s></div>
<div class="courses__price" style="color: red;">{{ course.buy_again_price|floatformat:"-2" }}₽</div> <div class="courses__price" style="color: red;">{{ price_with_discount|floatformat:"-2" }}₽</div>
{% else %} {% else %}
{% if course.old_price %} {% if course.old_price %}
<div class="courses__old-price mobile-hide"><s>{{ course.old_price|floatformat:"-2" }}₽</s></div> <div class="courses__old-price mobile-hide"><s>{{ course.old_price|floatformat:"-2" }}₽</s></div>

@ -1,5 +1,5 @@
{% extends "templates/lilcity/index.html" %} {% extends "templates/lilcity/index.html" %}
{% load static %} {% load static discounts_tags %}
{% load data_liked from data_liked %} {% load data_liked from data_liked %}
{% load rupluralize from plural %} {% load rupluralize from plural %}
{% block title %}{{ course.title }} - {{ block.super }}{% endblock title %} {% block title %}{{ course.title }} - {{ block.super }}{% endblock title %}
@ -136,6 +136,9 @@
</svg> </svg>
</div> </div>
<div class="meta__title"> <div class="meta__title">
{% get_price_for_item course.pk course.price discounts_per_course all_courses_discount as price_with_discount %}
{{ price_with_discount }}
{{ can_buy_again }}
{% if can_buy_again %} {% if can_buy_again %}
<s>{{ course.price|floatformat:"-2" }}₽</s> <s>{{ course.price|floatformat:"-2" }}₽</s>
{% else %} {% else %}

@ -17,7 +17,7 @@ from django.utils.translation import gettext as _
from django.utils.timezone import now from django.utils.timezone import now
from apps.content.models import Banner from apps.content.models import Banner
from apps.payment.models import AuthorBalance, CoursePayment from apps.payment.models import AuthorBalance, CoursePayment, Discount
from .models import Course, Like, Lesson, CourseComment, LessonComment, Category, CourseTags, Tag from .models import Course, Like, Lesson, CourseComment, LessonComment, Category, CourseTags, Tag
from .filters import CourseFilter from .filters import CourseFilter
from project.utils.db import ModelFieldsNames, format_sql, execute_sql from project.utils.db import ModelFieldsNames, format_sql, execute_sql
@ -198,8 +198,8 @@ class CourseView(DetailView):
# если это не админ или автор # если это не админ или автор
if not context.get('has_full_access'): if not context.get('has_full_access'):
# если это не опубл курс или это страница уроков, курс платный, а юзер не оплатил курс - 404 # если это не опубл курс или это страница уроков, курс платный, а юзер не оплатил курс - 404
if (self.object.status != Course.PUBLISHED) or \ if (self.object.status != Course.PUBLISHED) or (self.only_lessons and self.object.price and
(self.only_lessons and self.object.price and not context.get('paid')): not context.get('paid')):
raise Http404 raise Http404
return response return response
@ -246,10 +246,14 @@ class CourseView(DetailView):
]) ])
payment = payments.filter(access_expire__gte=now().date()).order_by('-access_expire').first() payment = payments.filter(access_expire__gte=now().date()).order_by('-access_expire').first()
context['payment'] = payment context['payment'] = payment
context['access_duration'] = ((payment.access_expire - now().date()).days + 1) if payment else self.object.access_duration context['access_duration'] = ((payment.access_expire - now().date()).days + 1) if payment else \
self.object.access_duration
context['paid'] = bool(payment) context['paid'] = bool(payment)
context['can_buy_again'] = bool(self.object.price) and (context['access_duration'] <= 7 if payment else context['can_buy_again'] = bool(self.object.price) and (context['access_duration'] <= 7 if payment else
payments.filter(access_expire__lt=now().date()).exists()) payments.filter(access_expire__lt=now().date())
.exists())
all_courses_discount, courses_discounts = Discount.objects.get_courses_discounts(user=self.request.user,
course=self.object)
context['pending'] = self.object.payments.filter( context['pending'] = self.object.payments.filter(
user=self.request.user, user=self.request.user,
status=Pingback.PINGBACK_TYPE_RISK_UNDER_REVIEW, status=Pingback.PINGBACK_TYPE_RISK_UNDER_REVIEW,
@ -260,8 +264,10 @@ class CourseView(DetailView):
context['is_owner'] = self.object.author == self.request.user context['is_owner'] = self.object.author == self.request.user
context['is_admin'] = self.request.user.role == User.ADMIN_ROLE context['is_admin'] = self.request.user.role == User.ADMIN_ROLE
context['has_full_access'] = context['is_owner'] or context['is_admin'] context['has_full_access'] = context['is_owner'] or context['is_admin']
else:
context['course_price'] = self.object.price / 2 if context.get('can_buy_again') else self.object.price all_courses_discount, courses_discounts = Discount.objects.get_courses_discounts(course=self.object)
context['all_courses_discount'] = all_courses_discount
context['discounts_per_course'] = courses_discounts
return context return context
def get_queryset(self): def get_queryset(self):
@ -353,12 +359,11 @@ class CoursesView(ListView):
context['category'] = Category.objects.filter(title__iexact=context.get('cat')[0]).values_list( context['category'] = Category.objects.filter(title__iexact=context.get('cat')[0]).values_list(
'id', flat=True)[:1] 'id', flat=True)[:1]
if self.request.user.is_authenticated: if self.request.user.is_authenticated:
can_buy_again_courses = list(CoursePayment.objects.filter(user=self.request.user, all_courses_discount, courses_discounts = Discount.objects.get_courses_discounts(user=self.request.user)
status__in=CoursePayment.PW_PAID_STATUSES, else:
access_expire__lte=now().date() + timedelta(7)).values_list('course_id', flat=True)) all_courses_discount, courses_discounts = Discount.objects.get_courses_discounts()
for course in context['course_items']: context['all_courses_discount'] = all_courses_discount
if course.id in can_buy_again_courses: context['discounts_per_course'] = courses_discounts
course.buy_again_price = course.price / 2
return context return context
def get_template_names(self): def get_template_names(self):

@ -443,7 +443,10 @@ class DiscountManager(models.Manager):
actual_discounts = actual_discounts.filter(course=course) actual_discounts = actual_discounts.filter(course=course)
courses_max_discounts = actual_discounts.filter(product=Discount.PRODUCT_ONE_COURSE).values('course')\ courses_max_discounts = actual_discounts.filter(product=Discount.PRODUCT_ONE_COURSE).values('course')\
.annotate(max_discount=Max('value')) .annotate(max_discount=Max('value'))
return all_courses_max_discount, courses_max_discounts discounts_per_course = {}
for discount in courses_max_discounts:
discounts_per_course[discount['course']] = discount['max_discount']
return all_courses_max_discount['max_discount'], discounts_per_course
def get_packages_discounts(self, user=None, package=None): def get_packages_discounts(self, user=None, package=None):
actual_discounts = self.get_actual_discounts(user=user) actual_discounts = self.get_actual_discounts(user=user)
@ -453,7 +456,10 @@ class DiscountManager(models.Manager):
actual_discounts = actual_discounts.filter(package=package) actual_discounts = actual_discounts.filter(package=package)
packages_max_discounts = actual_discounts.filter(product=Discount.PRODUCT_ONE_PACKAGE).values('package') \ packages_max_discounts = actual_discounts.filter(product=Discount.PRODUCT_ONE_PACKAGE).values('package') \
.annotate(max_discount=Max('value')) .annotate(max_discount=Max('value'))
return all_packages_max_discount, packages_max_discounts discounts_per_package = {}
for discount in packages_max_discounts:
discounts_per_package[discount['package']] = discount['max_discount']
return all_packages_max_discount['max_discount'], discounts_per_package
class Discount(models.Model): class Discount(models.Model):
@ -502,6 +508,26 @@ class Discount(models.Model):
objects = DiscountManager() objects = DiscountManager()
@staticmethod
def get_price_with_discount(pk, price, discount_per_item, max_discount):
"""
Расчет суммы скидки для элемента, при расчете вычисляем максимально возможную скидку для элемента и
вычислем сумму с учетом скидки
:param pk: id элемента
:param price: Цена элемента без скидки
:param discount_per_item: Словарь со скидками, ключ id элемента, значение размер скидки
:param max_discount: Максимальная скидка на все элементы
:return: Цена с учетом скидки, если скидка нулевая, то возвращается первоначальная цена
"""
discount = discount_per_item.get(pk, 0)
if max_discount and max_discount > discount:
discount = max_discount
if discount > 0:
result = price - ((price * discount) / 100)
return result.quantize(Decimal('1.00'))
else:
return price
def __str__(self): def __str__(self):
return self.name return self.name

@ -0,0 +1,11 @@
from django import template
from apps.payment.models import Discount
register = template.Library()
@register.simple_tag()
def get_price_for_item(pk, item_price, discounts_items, max_discounts_for_all_items):
return Discount.get_price_with_discount(pk=pk, price=item_price, discount_per_item=discounts_items,
max_discount=max_discounts_for_all_items)

@ -1,4 +1,5 @@
from datetime import timedelta from datetime import timedelta
from decimal import Decimal
from django.test import TestCase from django.test import TestCase
from django.utils.timezone import now from django.utils.timezone import now
@ -23,9 +24,8 @@ class DiscountForCoursesModelTestCase(TestCase):
product=Discount.PRODUCT_ONE_COURSE) product=Discount.PRODUCT_ONE_COURSE)
all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts() all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts()
self.assertEqual(all_curses_discounts, {'max_discount': None}) self.assertEqual(all_curses_discounts, None)
self.assertEqual(discounts_for_courses[0], {'course': course_1.pk, 'max_discount': 30}) self.assertEqual(discounts_for_courses, {course_1.pk: 30, course_2.pk: 50})
self.assertEqual(discounts_for_courses[1], {'course': course_2.pk, 'max_discount': 50})
def test_greater_value_discount_without_user(self): def test_greater_value_discount_without_user(self):
course = CourseFactory.create() course = CourseFactory.create()
@ -35,8 +35,8 @@ class DiscountForCoursesModelTestCase(TestCase):
product=Discount.PRODUCT_ONE_COURSE) product=Discount.PRODUCT_ONE_COURSE)
all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts() all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts()
self.assertEqual(all_curses_discounts, {'max_discount': None}) self.assertEqual(all_curses_discounts, None)
self.assertEqual(discounts_for_courses[0], {'course': course.pk, 'max_discount': 50}) self.assertEqual(discounts_for_courses, {course.pk: 50})
def test_exclude_personal_discounts_without_user(self): def test_exclude_personal_discounts_without_user(self):
user_1 = UserFactory.create() user_1 = UserFactory.create()
@ -46,8 +46,8 @@ class DiscountForCoursesModelTestCase(TestCase):
DiscountFactory.create(end=now() + timedelta(days=5), value=50, course=course, DiscountFactory.create(end=now() + timedelta(days=5), value=50, course=course,
product=Discount.PRODUCT_ONE_COURSE, client=user_1) product=Discount.PRODUCT_ONE_COURSE, client=user_1)
all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts() all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts()
self.assertEqual(all_curses_discounts, {'max_discount': None}) self.assertEqual(all_curses_discounts, None)
self.assertEqual(discounts_for_courses[0], {'course': course.pk, 'max_discount': 30}) self.assertEqual(discounts_for_courses, {course.pk: 30})
def test_discount_for_one_course_and_all_courses(self): def test_discount_for_one_course_and_all_courses(self):
course = CourseFactory.create() course = CourseFactory.create()
@ -58,8 +58,8 @@ class DiscountForCoursesModelTestCase(TestCase):
DiscountFactory.create(end=now() + timedelta(days=5), value=10, product=Discount.PRODUCT_ALL_COURSES) DiscountFactory.create(end=now() + timedelta(days=5), value=10, product=Discount.PRODUCT_ALL_COURSES)
all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts() all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts()
self.assertEqual(all_curses_discounts, {'max_discount': 10}) self.assertEqual(all_curses_discounts, 10)
self.assertEqual(discounts_for_courses[0], {'course': course.pk, 'max_discount': 50}) self.assertEqual(discounts_for_courses, {course.pk: 50})
def test_personal_discounts(self): def test_personal_discounts(self):
course = CourseFactory.create() course = CourseFactory.create()
@ -70,8 +70,8 @@ class DiscountForCoursesModelTestCase(TestCase):
DiscountFactory.create(end=now() + timedelta(days=5), value=10, product=Discount.PRODUCT_ALL_COURSES) DiscountFactory.create(end=now() + timedelta(days=5), value=10, product=Discount.PRODUCT_ALL_COURSES)
all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts(user=self.user) all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts(user=self.user)
self.assertEqual(all_curses_discounts, {'max_discount': 10}) self.assertEqual(all_curses_discounts, 10)
self.assertEqual(discounts_for_courses[0], {'course': course.pk, 'max_discount': 50}) self.assertEqual(discounts_for_courses, {course.pk: 50})
def test_personal_discounts_multiple_users(self): def test_personal_discounts_multiple_users(self):
user_1 = UserFactory() user_1 = UserFactory()
@ -85,12 +85,12 @@ class DiscountForCoursesModelTestCase(TestCase):
client=self.user) client=self.user)
all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts(user=self.user) all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts(user=self.user)
self.assertEqual(all_curses_discounts, {'max_discount': 10}) self.assertEqual(all_curses_discounts, 10)
self.assertEqual(discounts_for_courses[0], {'course': course.pk, 'max_discount': 50}) self.assertEqual(discounts_for_courses, {course.pk: 50})
all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts(user=user_1) all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts(user=user_1)
self.assertEqual(all_curses_discounts, {'max_discount': None}) self.assertEqual(all_curses_discounts, None)
self.assertEqual(discounts_for_courses[0], {'course': course.pk, 'max_discount': 30}) self.assertEqual(discounts_for_courses, {course.pk: 30})
def test_discount_for_one_course_without_user(self): def test_discount_for_one_course_without_user(self):
course_1 = CourseFactory.create() course_1 = CourseFactory.create()
@ -105,9 +105,9 @@ class DiscountForCoursesModelTestCase(TestCase):
product=Discount.PRODUCT_ONE_COURSE) product=Discount.PRODUCT_ONE_COURSE)
all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts(user=None, course=course_1) all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts(user=None, course=course_1)
self.assertEqual(all_curses_discounts, {'max_discount': None}) self.assertEqual(all_curses_discounts, None)
self.assertEqual(len(discounts_for_courses), 1) self.assertEqual(len(discounts_for_courses), 1)
self.assertEqual(discounts_for_courses[0], {'course': course_1.pk, 'max_discount': 30}) self.assertEqual(discounts_for_courses, {course_1.pk: 30})
def test_discount_for_one_course_with_multiple_users(self): def test_discount_for_one_course_with_multiple_users(self):
user_1 = UserFactory.create() user_1 = UserFactory.create()
@ -130,15 +130,15 @@ class DiscountForCoursesModelTestCase(TestCase):
all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts(user=user_1, all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts(user=user_1,
course=course_1) course=course_1)
self.assertEqual(all_curses_discounts, {'max_discount': 10}) self.assertEqual(all_curses_discounts, 10)
self.assertEqual(len(discounts_for_courses), 1) self.assertEqual(len(discounts_for_courses), 1)
self.assertEqual(discounts_for_courses[0], {'course': course_1.pk, 'max_discount': 30}) self.assertEqual(discounts_for_courses, {course_1.pk: 30})
all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts(user=self.user, all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts(user=self.user,
course=course_1) course=course_1)
self.assertEqual(all_curses_discounts, {'max_discount': 50}) self.assertEqual(all_curses_discounts, 50)
self.assertEqual(len(discounts_for_courses), 1) self.assertEqual(len(discounts_for_courses), 1)
self.assertEqual(discounts_for_courses[0], {'course': course_1.pk, 'max_discount': 30}) self.assertEqual(discounts_for_courses, {course_1.pk: 30})
def test_not_active_discount(self): def test_not_active_discount(self):
DiscountFactory.create(end=now() + timedelta(days=5), value=60, product=Discount.PRODUCT_ALL_COURSES, DiscountFactory.create(end=now() + timedelta(days=5), value=60, product=Discount.PRODUCT_ALL_COURSES,
@ -147,7 +147,7 @@ class DiscountForCoursesModelTestCase(TestCase):
all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts() all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts()
self.assertEqual(all_curses_discounts, {'max_discount': 40}) self.assertEqual(all_curses_discounts, 40)
self.assertEqual(len(discounts_for_courses), 0) self.assertEqual(len(discounts_for_courses), 0)
def test_old_discount(self): def test_old_discount(self):
@ -157,7 +157,7 @@ class DiscountForCoursesModelTestCase(TestCase):
all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts() all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts()
self.assertEqual(all_curses_discounts, {'max_discount': 40}) self.assertEqual(all_curses_discounts, 40)
self.assertEqual(len(discounts_for_courses), 0) self.assertEqual(len(discounts_for_courses), 0)
def test_discount_from_the_future(self): def test_discount_from_the_future(self):
@ -167,7 +167,7 @@ class DiscountForCoursesModelTestCase(TestCase):
all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts() all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts()
self.assertEqual(all_curses_discounts, {'max_discount': 40}) self.assertEqual(all_curses_discounts, 40)
self.assertEqual(len(discounts_for_courses), 0) self.assertEqual(len(discounts_for_courses), 0)
@ -187,9 +187,8 @@ class DiscountForPackagesModelTestCase(TestCase):
product=Discount.PRODUCT_ONE_PACKAGE) product=Discount.PRODUCT_ONE_PACKAGE)
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts() all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts()
self.assertEqual(all_packages_discounts, {'max_discount': None}) self.assertEqual(all_packages_discounts, None)
self.assertEqual(discounts_for_packages[0], {'package': package_1.pk, 'max_discount': 30}) self.assertEqual(discounts_for_packages, {package_1.pk: 30, package_2.pk: 50})
self.assertEqual(discounts_for_packages[1], {'package': package_2.pk, 'max_discount': 50})
def test_greater_value_discount_without_user(self): def test_greater_value_discount_without_user(self):
package = PackageFactory.create() package = PackageFactory.create()
@ -199,8 +198,8 @@ class DiscountForPackagesModelTestCase(TestCase):
product=Discount.PRODUCT_ONE_PACKAGE) product=Discount.PRODUCT_ONE_PACKAGE)
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts() all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts()
self.assertEqual(all_packages_discounts, {'max_discount': None}) self.assertEqual(all_packages_discounts, None)
self.assertEqual(discounts_for_packages[0], {'package': package.pk, 'max_discount': 50}) self.assertEqual(discounts_for_packages, {package.pk: 50})
def test_exclude_personal_discounts_without_user(self): def test_exclude_personal_discounts_without_user(self):
user_1 = UserFactory.create() user_1 = UserFactory.create()
@ -210,8 +209,8 @@ class DiscountForPackagesModelTestCase(TestCase):
DiscountFactory.create(end=now() + timedelta(days=5), value=50, package=package, DiscountFactory.create(end=now() + timedelta(days=5), value=50, package=package,
product=Discount.PRODUCT_ONE_PACKAGE, client=user_1) product=Discount.PRODUCT_ONE_PACKAGE, client=user_1)
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts() all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts()
self.assertEqual(all_packages_discounts, {'max_discount': None}) self.assertEqual(all_packages_discounts, None)
self.assertEqual(discounts_for_packages[0], {'package': package.pk, 'max_discount': 30}) self.assertEqual(discounts_for_packages, {package.pk: 30})
def test_discount_for_one_package_and_all_packages(self): def test_discount_for_one_package_and_all_packages(self):
package = PackageFactory.create() package = PackageFactory.create()
@ -222,8 +221,8 @@ class DiscountForPackagesModelTestCase(TestCase):
DiscountFactory.create(end=now() + timedelta(days=5), value=10, product=Discount.PRODUCT_ALL_PACKAGES) DiscountFactory.create(end=now() + timedelta(days=5), value=10, product=Discount.PRODUCT_ALL_PACKAGES)
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts() all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts()
self.assertEqual(all_packages_discounts, {'max_discount': 10}) self.assertEqual(all_packages_discounts, 10)
self.assertEqual(discounts_for_packages[0], {'package': package.pk, 'max_discount': 50}) self.assertEqual(discounts_for_packages, {package.pk: 50})
def test_personal_discounts(self): def test_personal_discounts(self):
package = PackageFactory.create() package = PackageFactory.create()
@ -234,8 +233,8 @@ class DiscountForPackagesModelTestCase(TestCase):
DiscountFactory.create(end=now() + timedelta(days=5), value=10, product=Discount.PRODUCT_ALL_PACKAGES) DiscountFactory.create(end=now() + timedelta(days=5), value=10, product=Discount.PRODUCT_ALL_PACKAGES)
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts(user=self.user) all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts(user=self.user)
self.assertEqual(all_packages_discounts, {'max_discount': 10}) self.assertEqual(all_packages_discounts, 10)
self.assertEqual(discounts_for_packages[0], {'package': package.pk, 'max_discount': 50}) self.assertEqual(discounts_for_packages, {package.pk: 50})
def test_personal_discounts_multiple_users(self): def test_personal_discounts_multiple_users(self):
user_1 = UserFactory() user_1 = UserFactory()
@ -249,12 +248,12 @@ class DiscountForPackagesModelTestCase(TestCase):
client=self.user) client=self.user)
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts(user=self.user) all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts(user=self.user)
self.assertEqual(all_packages_discounts, {'max_discount': 10}) self.assertEqual(all_packages_discounts, 10)
self.assertEqual(discounts_for_packages[0], {'package': package.pk, 'max_discount': 50}) self.assertEqual(discounts_for_packages, {package.pk: 50})
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts(user=user_1) all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts(user=user_1)
self.assertEqual(all_packages_discounts, {'max_discount': None}) self.assertEqual(all_packages_discounts, None)
self.assertEqual(discounts_for_packages[0], {'package': package.pk, 'max_discount': 30}) self.assertEqual(discounts_for_packages, {package.pk: 30})
def test_discount_for_one_package_without_user(self): def test_discount_for_one_package_without_user(self):
package_1 = PackageFactory.create() package_1 = PackageFactory.create()
@ -270,9 +269,9 @@ class DiscountForPackagesModelTestCase(TestCase):
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts(user=None, all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts(user=None,
package=package_1) package=package_1)
self.assertEqual(all_packages_discounts, {'max_discount': None}) self.assertEqual(all_packages_discounts, None)
self.assertEqual(len(discounts_for_packages), 1) self.assertEqual(len(discounts_for_packages), 1)
self.assertEqual(discounts_for_packages[0], {'package': package_1.pk, 'max_discount': 30}) self.assertEqual(discounts_for_packages, {package_1.pk: 30})
def test_discount_for_one_package_with_multiple_users(self): def test_discount_for_one_package_with_multiple_users(self):
user_1 = UserFactory.create() user_1 = UserFactory.create()
@ -295,15 +294,15 @@ class DiscountForPackagesModelTestCase(TestCase):
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts(user=user_1, all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts(user=user_1,
package=package_1) package=package_1)
self.assertEqual(all_packages_discounts, {'max_discount': 10}) self.assertEqual(all_packages_discounts, 10)
self.assertEqual(len(discounts_for_packages), 1) self.assertEqual(len(discounts_for_packages), 1)
self.assertEqual(discounts_for_packages[0], {'package': package_1.pk, 'max_discount': 30}) self.assertEqual(discounts_for_packages, {package_1.pk: 30})
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts(user=self.user, all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts(user=self.user,
package=package_1) package=package_1)
self.assertEqual(all_packages_discounts, {'max_discount': 50}) self.assertEqual(all_packages_discounts, 50)
self.assertEqual(len(discounts_for_packages), 1) self.assertEqual(len(discounts_for_packages), 1)
self.assertEqual(discounts_for_packages[0], {'package': package_1.pk, 'max_discount': 30}) self.assertEqual(discounts_for_packages, {package_1.pk: 30})
def test_not_active_discount(self): def test_not_active_discount(self):
DiscountFactory.create(end=now() + timedelta(days=5), value=60, product=Discount.PRODUCT_ALL_PACKAGES, DiscountFactory.create(end=now() + timedelta(days=5), value=60, product=Discount.PRODUCT_ALL_PACKAGES,
@ -312,7 +311,7 @@ class DiscountForPackagesModelTestCase(TestCase):
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts() all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts()
self.assertEqual(all_packages_discounts, {'max_discount': 40}) self.assertEqual(all_packages_discounts, 40)
self.assertEqual(len(discounts_for_packages), 0) self.assertEqual(len(discounts_for_packages), 0)
def test_old_discount(self): def test_old_discount(self):
@ -322,7 +321,7 @@ class DiscountForPackagesModelTestCase(TestCase):
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts() all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts()
self.assertEqual(all_packages_discounts, {'max_discount': 40}) self.assertEqual(all_packages_discounts, 40)
self.assertEqual(len(discounts_for_packages), 0) self.assertEqual(len(discounts_for_packages), 0)
def test_discount_from_the_future(self): def test_discount_from_the_future(self):
@ -332,5 +331,95 @@ class DiscountForPackagesModelTestCase(TestCase):
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts() all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts()
self.assertEqual(all_packages_discounts, {'max_discount': 40}) self.assertEqual(all_packages_discounts, 40)
self.assertEqual(len(discounts_for_packages), 0) self.assertEqual(len(discounts_for_packages), 0)
class DiscountCalculateTestCase(TestCase):
def test_discount_with_package(self):
package = PackageFactory.create(price=Decimal('5000.5'))
DiscountFactory.create(end=now() + timedelta(days=5), value=40, product=Discount.PRODUCT_ONE_PACKAGE,
package=package)
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts()
value = Discount.get_price_with_discount(package.pk, package.price, discounts_for_packages,
all_packages_discounts)
self.assertEqual(value, Decimal('3000.3'))
def test_discount_with_package_discount_for_all(self):
package = PackageFactory.create(price=Decimal('5000'))
DiscountFactory.create(end=now() + timedelta(days=5), value=40, product=Discount.PRODUCT_ALL_PACKAGES)
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts()
value = Discount.get_price_with_discount(package.pk, package.price, discounts_for_packages,
all_packages_discounts)
self.assertEqual(value, Decimal('3000'))
def test_discount_with_package_if_all_discount_gt_discount_package(self):
package = PackageFactory.create(price=Decimal('5000'))
DiscountFactory.create(end=now() + timedelta(days=5), value=50, product=Discount.PRODUCT_ALL_PACKAGES)
DiscountFactory.create(end=now() + timedelta(days=5), value=30, product=Discount.PRODUCT_ONE_PACKAGE,
package=package)
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts()
value = Discount.get_price_with_discount(package.pk, package.price, discounts_for_packages,
all_packages_discounts)
self.assertEqual(value, Decimal('2500'))
def test_discount_with_package_if_all_discount_lt_discount_package(self):
package = PackageFactory.create(price=Decimal('5000'))
DiscountFactory.create(end=now() + timedelta(days=5), value=50, product=Discount.PRODUCT_ALL_PACKAGES)
DiscountFactory.create(end=now() + timedelta(days=5), value=60, product=Discount.PRODUCT_ONE_PACKAGE,
package=package)
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts()
value = Discount.get_price_with_discount(package.pk, package.price, discounts_for_packages,
all_packages_discounts)
self.assertEqual(value, Decimal('2000'))
def test_discount_with_package_without_discount(self):
package = PackageFactory.create(price=Decimal('5000'))
all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts()
value = Discount.get_price_with_discount(package.pk, package.price, discounts_for_packages,
all_packages_discounts)
self.assertEqual(value, Decimal('5000'))
def test_discount_with_course(self):
course = CourseFactory.create(price=Decimal('5000.5'))
DiscountFactory.create(end=now() + timedelta(days=5), value=40, product=Discount.PRODUCT_ONE_COURSE,
course=course)
all_courses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts()
value = Discount.get_price_with_discount(course.pk, course.price, discounts_for_courses,
all_courses_discounts)
self.assertEqual(value, Decimal('3000.3'))
def test_discount_with_course_discount_for_all(self):
course = CourseFactory.create(price=Decimal('5000'))
DiscountFactory.create(end=now() + timedelta(days=5), value=40, product=Discount.PRODUCT_ALL_COURSES)
all_courses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts()
value = Discount.get_price_with_discount(course.pk, course.price, discounts_for_courses, all_courses_discounts)
self.assertEqual(value, Decimal('3000'))
def test_discount_with_course_if_all_discount_gt_discount_course(self):
course = CourseFactory.create(price=Decimal('5000'))
DiscountFactory.create(end=now() + timedelta(days=5), value=50, product=Discount.PRODUCT_ALL_COURSES)
DiscountFactory.create(end=now() + timedelta(days=5), value=30, product=Discount.PRODUCT_ONE_COURSE,
course=course)
all_courses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts()
value = Discount.get_price_with_discount(course.pk, course.price, discounts_for_courses,
all_courses_discounts)
self.assertEqual(value, Decimal('2500'))
def test_discount_with_course_if_all_discount_lt_discount_course(self):
course = CourseFactory.create(price=Decimal('5000'))
DiscountFactory.create(end=now() + timedelta(days=5), value=50, product=Discount.PRODUCT_ALL_COURSES)
DiscountFactory.create(end=now() + timedelta(days=5), value=60, product=Discount.PRODUCT_ONE_COURSE,
course=course)
all_courses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts()
value = Discount.get_price_with_discount(course.pk, course.price, discounts_for_courses,
all_courses_discounts)
self.assertEqual(value, Decimal('2000'))
def test_discount_with_course_without_discount(self):
course = CourseFactory.create(price=Decimal('5000'))
all_courses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts()
value = Discount.get_price_with_discount(course.pk, course.price, discounts_for_courses,
all_courses_discounts)
self.assertEqual(value, Decimal('5000'))

@ -1,6 +1,5 @@
{% extends "templates/lilcity/index.html" %} {% extends "templates/lilcity/index.html" %}
{% load static %} {% load static plural discounts_tags %}
{% load plural %}
{% block content %} {% block content %}
<div class="section"> <div class="section">
@ -18,9 +17,12 @@
</div> </div>
<div class="package__desc">{{ package.description }}</div> <div class="package__desc">{{ package.description }}</div>
<div class="package__price"> <div class="package__price">
{{ package.price|floatformat }}р {% get_price_for_item package.pk package.price discounts_per_package discounts_all_packages as price_with_discount %}
{% if package.high_price %} {% if price_with_discount < package.price %}
<div class="package__high-price">&nbsp;{{ package.high_price|floatformat }}р&nbsp;</div> {{ price_with_discount|floatformat }}р
<div class="package__high-price">&nbsp;{{ package.price|floatformat }}р&nbsp;</div>
{% else %}
{{ package.price|floatformat }}р
{% endif %} {% endif %}
</div> </div>
<div class="package__options"> <div class="package__options">

@ -10,7 +10,7 @@ from paymentwall.pingback import Pingback
from apps.course.models import Course from apps.course.models import Course
from apps.school.models import SchoolSchedule from apps.school.models import SchoolSchedule
from apps.payment.models import SchoolPayment, UserGiftCertificate, Payment, DrawingCampPayment from apps.payment.models import SchoolPayment, UserGiftCertificate, Payment, DrawingCampPayment, Discount
from apps.content.models import Banner, Package from apps.content.models import Banner, Package
User = get_user_model() User = get_user_model()
@ -159,9 +159,14 @@ class PackagesView(TemplateView):
def get_context_data(self): def get_context_data(self):
context = super().get_context_data() context = super().get_context_data()
context['packages'] = Package.objects.all()[:4] context['packages'] = Package.objects.all()[:4]
if self.request.user.is_authenticated:
courses_discounts_all, courses_discounts = Discount.objects.get_packages_discounts(user=self.request.user)
else:
courses_discounts_all, courses_discounts = Discount.objects.get_packages_discounts()
context['discounts_all_packages'] = courses_discounts_all
context['discounts_per_package'] = courses_discounts
context['banners'] = Banner.get_for_page(Banner.PAGE_PACKAGES)[:1] context['banners'] = Banner.get_for_page(Banner.PAGE_PACKAGES)[:1]
last_school_payment = None last_school_payment = None
school_end = date(now().year, 5, 31)
today = now().date() today = now().date()
if self.request.user.is_authenticated: if self.request.user.is_authenticated:
last_school_payment = SchoolPayment.objects.filter( last_school_payment = SchoolPayment.objects.filter(
@ -169,16 +174,9 @@ class PackagesView(TemplateView):
date_end__gte=today, date_end__gte=today,
status__in=Payment.PW_PAID_STATUSES, status__in=Payment.PW_PAID_STATUSES,
).last() ).last()
context['last_school_payment'] = last_school_payment
if last_school_payment: if last_school_payment:
next_month = (last_school_payment.date_end + timedelta(1)).month
context['next_buy_date'] = last_school_payment.date_end + \ context['next_buy_date'] = last_school_payment.date_end + \
timedelta(1) timedelta(1)
context['school_months_left'] = (school_end.month - next_month
if next_month <= school_end.month
else (school_end.month + 13) - next_month)
else: else:
context['school_months_left'] = (school_end.month - today.month context['next_buy_date'] = None
if today.month <= school_end.month
else (school_end.month + 13) - today.month)
return context return context

Loading…
Cancel
Save