diff --git a/apps/course/templates/course/_items.html b/apps/course/templates/course/_items.html index f1cd65cf..e8c189d7 100644 --- a/apps/course/templates/course/_items.html +++ b/apps/course/templates/course/_items.html @@ -1,5 +1,4 @@ -{% load thumbnail %} -{% load static %} +{% load thumbnail static discounts_tags %} {% load data_liked from data_liked %}
{{ course.category | upper }} {% 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 %}
{{ course.price|floatformat:"-2" }}₽
-
{{ course.buy_again_price|floatformat:"-2" }}₽
+
{{ price_with_discount|floatformat:"-2" }}₽
{% else %} {% if course.old_price %}
{{ course.old_price|floatformat:"-2" }}₽
diff --git a/apps/course/templates/course/course.html b/apps/course/templates/course/course.html index db228e96..9635651d 100644 --- a/apps/course/templates/course/course.html +++ b/apps/course/templates/course/course.html @@ -1,5 +1,5 @@ {% extends "templates/lilcity/index.html" %} -{% load static %} +{% load static discounts_tags %} {% load data_liked from data_liked %} {% load rupluralize from plural %} {% block title %}{{ course.title }} - {{ block.super }}{% endblock title %} @@ -136,6 +136,9 @@
+ {% 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 %} {{ course.price|floatformat:"-2" }}₽ {% else %} diff --git a/apps/course/views.py b/apps/course/views.py index d4bd0298..53f01239 100644 --- a/apps/course/views.py +++ b/apps/course/views.py @@ -17,7 +17,7 @@ from django.utils.translation import gettext as _ from django.utils.timezone import now 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 .filters import CourseFilter from project.utils.db import ModelFieldsNames, format_sql, execute_sql @@ -198,8 +198,8 @@ class CourseView(DetailView): # если это не админ или автор if not context.get('has_full_access'): # если это не опубл курс или это страница уроков, курс платный, а юзер не оплатил курс - 404 - if (self.object.status != Course.PUBLISHED) or \ - (self.only_lessons and self.object.price and not context.get('paid')): + if (self.object.status != Course.PUBLISHED) or (self.only_lessons and self.object.price and + not context.get('paid')): raise Http404 return response @@ -246,10 +246,14 @@ class CourseView(DetailView): ]) payment = payments.filter(access_expire__gte=now().date()).order_by('-access_expire').first() 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['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( user=self.request.user, 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_admin'] = self.request.user.role == User.ADMIN_ROLE context['has_full_access'] = context['is_owner'] or context['is_admin'] - - context['course_price'] = self.object.price / 2 if context.get('can_buy_again') else self.object.price + else: + 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 def get_queryset(self): @@ -353,12 +359,11 @@ class CoursesView(ListView): context['category'] = Category.objects.filter(title__iexact=context.get('cat')[0]).values_list( 'id', flat=True)[:1] if self.request.user.is_authenticated: - can_buy_again_courses = list(CoursePayment.objects.filter(user=self.request.user, - status__in=CoursePayment.PW_PAID_STATUSES, - access_expire__lte=now().date() + timedelta(7)).values_list('course_id', flat=True)) - for course in context['course_items']: - if course.id in can_buy_again_courses: - course.buy_again_price = course.price / 2 + all_courses_discount, courses_discounts = Discount.objects.get_courses_discounts(user=self.request.user) + else: + all_courses_discount, courses_discounts = Discount.objects.get_courses_discounts() + context['all_courses_discount'] = all_courses_discount + context['discounts_per_course'] = courses_discounts return context def get_template_names(self): diff --git a/apps/payment/models.py b/apps/payment/models.py index b8afc76b..f2bc02a5 100644 --- a/apps/payment/models.py +++ b/apps/payment/models.py @@ -443,7 +443,10 @@ class DiscountManager(models.Manager): actual_discounts = actual_discounts.filter(course=course) courses_max_discounts = actual_discounts.filter(product=Discount.PRODUCT_ONE_COURSE).values('course')\ .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): actual_discounts = self.get_actual_discounts(user=user) @@ -453,7 +456,10 @@ class DiscountManager(models.Manager): actual_discounts = actual_discounts.filter(package=package) packages_max_discounts = actual_discounts.filter(product=Discount.PRODUCT_ONE_PACKAGE).values('package') \ .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): @@ -502,6 +508,26 @@ class Discount(models.Model): 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): return self.name diff --git a/apps/payment/templatetags/__init__.py b/apps/payment/templatetags/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/payment/templatetags/discounts_tags.py b/apps/payment/templatetags/discounts_tags.py new file mode 100644 index 00000000..f889debe --- /dev/null +++ b/apps/payment/templatetags/discounts_tags.py @@ -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) diff --git a/apps/payment/tests/tests_models.py b/apps/payment/tests/tests_models.py index e746a2e8..4f4261da 100644 --- a/apps/payment/tests/tests_models.py +++ b/apps/payment/tests/tests_models.py @@ -1,4 +1,5 @@ from datetime import timedelta +from decimal import Decimal from django.test import TestCase from django.utils.timezone import now @@ -23,9 +24,8 @@ class DiscountForCoursesModelTestCase(TestCase): product=Discount.PRODUCT_ONE_COURSE) all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts() - self.assertEqual(all_curses_discounts, {'max_discount': None}) - self.assertEqual(discounts_for_courses[0], {'course': course_1.pk, 'max_discount': 30}) - self.assertEqual(discounts_for_courses[1], {'course': course_2.pk, 'max_discount': 50}) + self.assertEqual(all_curses_discounts, None) + self.assertEqual(discounts_for_courses, {course_1.pk: 30, course_2.pk: 50}) def test_greater_value_discount_without_user(self): course = CourseFactory.create() @@ -35,8 +35,8 @@ class DiscountForCoursesModelTestCase(TestCase): product=Discount.PRODUCT_ONE_COURSE) all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts() - self.assertEqual(all_curses_discounts, {'max_discount': None}) - self.assertEqual(discounts_for_courses[0], {'course': course.pk, 'max_discount': 50}) + self.assertEqual(all_curses_discounts, None) + self.assertEqual(discounts_for_courses, {course.pk: 50}) def test_exclude_personal_discounts_without_user(self): user_1 = UserFactory.create() @@ -46,8 +46,8 @@ class DiscountForCoursesModelTestCase(TestCase): DiscountFactory.create(end=now() + timedelta(days=5), value=50, course=course, product=Discount.PRODUCT_ONE_COURSE, client=user_1) all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts() - self.assertEqual(all_curses_discounts, {'max_discount': None}) - self.assertEqual(discounts_for_courses[0], {'course': course.pk, 'max_discount': 30}) + self.assertEqual(all_curses_discounts, None) + self.assertEqual(discounts_for_courses, {course.pk: 30}) def test_discount_for_one_course_and_all_courses(self): course = CourseFactory.create() @@ -58,8 +58,8 @@ class DiscountForCoursesModelTestCase(TestCase): 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() - self.assertEqual(all_curses_discounts, {'max_discount': 10}) - self.assertEqual(discounts_for_courses[0], {'course': course.pk, 'max_discount': 50}) + self.assertEqual(all_curses_discounts, 10) + self.assertEqual(discounts_for_courses, {course.pk: 50}) def test_personal_discounts(self): course = CourseFactory.create() @@ -70,8 +70,8 @@ class DiscountForCoursesModelTestCase(TestCase): 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) - self.assertEqual(all_curses_discounts, {'max_discount': 10}) - self.assertEqual(discounts_for_courses[0], {'course': course.pk, 'max_discount': 50}) + self.assertEqual(all_curses_discounts, 10) + self.assertEqual(discounts_for_courses, {course.pk: 50}) def test_personal_discounts_multiple_users(self): user_1 = UserFactory() @@ -85,12 +85,12 @@ class DiscountForCoursesModelTestCase(TestCase): client=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(discounts_for_courses[0], {'course': course.pk, 'max_discount': 50}) + self.assertEqual(all_curses_discounts, 10) + self.assertEqual(discounts_for_courses, {course.pk: 50}) all_curses_discounts, discounts_for_courses = Discount.objects.get_courses_discounts(user=user_1) - self.assertEqual(all_curses_discounts, {'max_discount': None}) - self.assertEqual(discounts_for_courses[0], {'course': course.pk, 'max_discount': 30}) + self.assertEqual(all_curses_discounts, None) + self.assertEqual(discounts_for_courses, {course.pk: 30}) def test_discount_for_one_course_without_user(self): course_1 = CourseFactory.create() @@ -105,9 +105,9 @@ class DiscountForCoursesModelTestCase(TestCase): product=Discount.PRODUCT_ONE_COURSE) 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(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): 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, 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(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, 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(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): 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() - self.assertEqual(all_curses_discounts, {'max_discount': 40}) + self.assertEqual(all_curses_discounts, 40) self.assertEqual(len(discounts_for_courses), 0) def test_old_discount(self): @@ -157,7 +157,7 @@ class DiscountForCoursesModelTestCase(TestCase): 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) 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() - self.assertEqual(all_curses_discounts, {'max_discount': 40}) + self.assertEqual(all_curses_discounts, 40) self.assertEqual(len(discounts_for_courses), 0) @@ -187,9 +187,8 @@ class DiscountForPackagesModelTestCase(TestCase): product=Discount.PRODUCT_ONE_PACKAGE) all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts() - self.assertEqual(all_packages_discounts, {'max_discount': None}) - self.assertEqual(discounts_for_packages[0], {'package': package_1.pk, 'max_discount': 30}) - self.assertEqual(discounts_for_packages[1], {'package': package_2.pk, 'max_discount': 50}) + self.assertEqual(all_packages_discounts, None) + self.assertEqual(discounts_for_packages, {package_1.pk: 30, package_2.pk: 50}) def test_greater_value_discount_without_user(self): package = PackageFactory.create() @@ -199,8 +198,8 @@ class DiscountForPackagesModelTestCase(TestCase): product=Discount.PRODUCT_ONE_PACKAGE) all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts() - self.assertEqual(all_packages_discounts, {'max_discount': None}) - self.assertEqual(discounts_for_packages[0], {'package': package.pk, 'max_discount': 50}) + self.assertEqual(all_packages_discounts, None) + self.assertEqual(discounts_for_packages, {package.pk: 50}) def test_exclude_personal_discounts_without_user(self): user_1 = UserFactory.create() @@ -210,8 +209,8 @@ class DiscountForPackagesModelTestCase(TestCase): DiscountFactory.create(end=now() + timedelta(days=5), value=50, package=package, product=Discount.PRODUCT_ONE_PACKAGE, client=user_1) all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts() - self.assertEqual(all_packages_discounts, {'max_discount': None}) - self.assertEqual(discounts_for_packages[0], {'package': package.pk, 'max_discount': 30}) + self.assertEqual(all_packages_discounts, None) + self.assertEqual(discounts_for_packages, {package.pk: 30}) def test_discount_for_one_package_and_all_packages(self): package = PackageFactory.create() @@ -222,8 +221,8 @@ class DiscountForPackagesModelTestCase(TestCase): 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() - self.assertEqual(all_packages_discounts, {'max_discount': 10}) - self.assertEqual(discounts_for_packages[0], {'package': package.pk, 'max_discount': 50}) + self.assertEqual(all_packages_discounts, 10) + self.assertEqual(discounts_for_packages, {package.pk: 50}) def test_personal_discounts(self): package = PackageFactory.create() @@ -234,8 +233,8 @@ class DiscountForPackagesModelTestCase(TestCase): 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) - self.assertEqual(all_packages_discounts, {'max_discount': 10}) - self.assertEqual(discounts_for_packages[0], {'package': package.pk, 'max_discount': 50}) + self.assertEqual(all_packages_discounts, 10) + self.assertEqual(discounts_for_packages, {package.pk: 50}) def test_personal_discounts_multiple_users(self): user_1 = UserFactory() @@ -249,12 +248,12 @@ class DiscountForPackagesModelTestCase(TestCase): client=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(discounts_for_packages[0], {'package': package.pk, 'max_discount': 50}) + self.assertEqual(all_packages_discounts, 10) + self.assertEqual(discounts_for_packages, {package.pk: 50}) all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts(user=user_1) - self.assertEqual(all_packages_discounts, {'max_discount': None}) - self.assertEqual(discounts_for_packages[0], {'package': package.pk, 'max_discount': 30}) + self.assertEqual(all_packages_discounts, None) + self.assertEqual(discounts_for_packages, {package.pk: 30}) def test_discount_for_one_package_without_user(self): package_1 = PackageFactory.create() @@ -270,9 +269,9 @@ class DiscountForPackagesModelTestCase(TestCase): all_packages_discounts, discounts_for_packages = Discount.objects.get_packages_discounts(user=None, 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(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): 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, 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(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, 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(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): 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() - self.assertEqual(all_packages_discounts, {'max_discount': 40}) + self.assertEqual(all_packages_discounts, 40) self.assertEqual(len(discounts_for_packages), 0) def test_old_discount(self): @@ -322,7 +321,7 @@ class DiscountForPackagesModelTestCase(TestCase): 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) 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() - self.assertEqual(all_packages_discounts, {'max_discount': 40}) + self.assertEqual(all_packages_discounts, 40) 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')) diff --git a/project/templates/lilcity/packages.html b/project/templates/lilcity/packages.html index 11e8ebd2..152eed23 100644 --- a/project/templates/lilcity/packages.html +++ b/project/templates/lilcity/packages.html @@ -1,6 +1,5 @@ {% extends "templates/lilcity/index.html" %} -{% load static %} -{% load plural %} +{% load static plural discounts_tags %} {% block content %}
@@ -18,9 +17,12 @@
{{ package.description }}
- {{ package.price|floatformat }}р - {% if package.high_price %} -
 {{ package.high_price|floatformat }}р 
+ {% get_price_for_item package.pk package.price discounts_per_package discounts_all_packages as price_with_discount %} + {% if price_with_discount < package.price %} + {{ price_with_discount|floatformat }}р +
 {{ package.price|floatformat }}р 
+ {% else %} + {{ package.price|floatformat }}р {% endif %}
diff --git a/project/views.py b/project/views.py index 9c3ac5b2..494cee57 100644 --- a/project/views.py +++ b/project/views.py @@ -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, DrawingCampPayment +from apps.payment.models import SchoolPayment, UserGiftCertificate, Payment, DrawingCampPayment, Discount from apps.content.models import Banner, Package User = get_user_model() @@ -159,9 +159,14 @@ class PackagesView(TemplateView): def get_context_data(self): context = super().get_context_data() 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] last_school_payment = None - school_end = date(now().year, 5, 31) today = now().date() if self.request.user.is_authenticated: last_school_payment = SchoolPayment.objects.filter( @@ -169,16 +174,9 @@ class PackagesView(TemplateView): date_end__gte=today, status__in=Payment.PW_PAID_STATUSES, ).last() - context['last_school_payment'] = 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 + \ 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: - context['school_months_left'] = (school_end.month - today.month - if today.month <= school_end.month - else (school_end.month + 13) - today.month) + context['next_buy_date'] = None return context