From 8852dcf915c37f49f115b0e1bdeda09e4c9d14e8 Mon Sep 17 00:00:00 2001 From: gzbender Date: Mon, 23 Sep 2019 09:33:31 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9C=D0=B5=D1=82=D1=80=D0=B8=D0=BA=D0=B0=20/?= =?UTF-8?q?=20=D0=9F=D0=B5=D1=80=D0=B5=D0=B4=D0=B0=D0=B2=D0=B0=D1=82=D1=8C?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=BA=D1=83=D0=BF=D0=BA=D0=B8=20(=D0=B8=D0=BD?= =?UTF-8?q?=D1=82=D0=B5=D0=B3=D1=80=D0=B0=D1=86=D0=B8=D1=8F=20ecommerce)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/course/templates/course/course.html | 7 +- apps/course/templatetags/lil_utils.py | 12 +++ .../payment/course_payment_success.html | 12 --- .../payment/gift_certificate_item.html | 1 + .../gift_certificate_payment_success.html | 13 --- apps/payment/templates/payment/pay.html | 70 ++++++++++++--- .../templates/payment/payment_success.html | 64 ++++++++++++-- apps/payment/views.py | 72 ++++++++++++---- project/templates/blocks/lil_store_js.html | 13 +-- project/templates/lilcity/packages.html | 1 + project/urls.py | 6 +- web/src/js/app.js | 1 + web/src/js/modules/gtag.js | 86 ++++++++++++++++++- 13 files changed, 280 insertions(+), 78 deletions(-) create mode 100644 apps/course/templatetags/lil_utils.py delete mode 100644 apps/payment/templates/payment/course_payment_success.html delete mode 100644 apps/payment/templates/payment/gift_certificate_payment_success.html diff --git a/apps/course/templates/course/course.html b/apps/course/templates/course/course.html index cd10eaff..769aaf9c 100644 --- a/apps/course/templates/course/course.html +++ b/apps/course/templates/course/course.html @@ -394,6 +394,9 @@ {% block foot %} {% include "templates/blocks/popup_course_buy.html" %} +{% endblock foot %} + +{% block foot_js %} -{% endblock foot %} +{% endblock foot_js %} diff --git a/apps/course/templatetags/lil_utils.py b/apps/course/templatetags/lil_utils.py new file mode 100644 index 00000000..feb6ac93 --- /dev/null +++ b/apps/course/templatetags/lil_utils.py @@ -0,0 +1,12 @@ +from django import template + +register = template.Library() + + +@register.simple_tag(takes_context=True) +def same_url(context, **kwargs): + request = context.get('request') + args = request.GET.copy() + args.update(kwargs) + return '%s?%s' % (request.path, args.urlencode()) + diff --git a/apps/payment/templates/payment/course_payment_success.html b/apps/payment/templates/payment/course_payment_success.html deleted file mode 100644 index 04139183..00000000 --- a/apps/payment/templates/payment/course_payment_success.html +++ /dev/null @@ -1,12 +0,0 @@ -{% extends "templates/lilcity/index.html" %} {% load static %} {% block content %} -
-
-
-
Вы успешно приобрели курс!
- -
-
-
-{% endblock content %} diff --git a/apps/payment/templates/payment/gift_certificate_item.html b/apps/payment/templates/payment/gift_certificate_item.html index 7d4d3d8f..3ee2a6f5 100644 --- a/apps/payment/templates/payment/gift_certificate_item.html +++ b/apps/payment/templates/payment/gift_certificate_item.html @@ -28,6 +28,7 @@ Купить сертификат diff --git a/apps/payment/templates/payment/gift_certificate_payment_success.html b/apps/payment/templates/payment/gift_certificate_payment_success.html deleted file mode 100644 index 793eb25e..00000000 --- a/apps/payment/templates/payment/gift_certificate_payment_success.html +++ /dev/null @@ -1,13 +0,0 @@ -{% extends "templates/lilcity/index.html" %} {% load static %} {% block content %} -
-
-
-
Вы успешно приобрели подарочный сертификат!
-
Мы отправили письмо с сертификатом на вашу почту.
- -
-
-
-{% endblock content %} diff --git a/apps/payment/templates/payment/pay.html b/apps/payment/templates/payment/pay.html index ec26e9ca..b5088262 100644 --- a/apps/payment/templates/payment/pay.html +++ b/apps/payment/templates/payment/pay.html @@ -1,21 +1,24 @@ {% extends "templates/lilcity/index.html" %} {% load static %} {% load rupluralize from plural %} +{% load same_url from lil_utils %} {% block content %}
- {% if school and request.user.bonus and not payment.bonus %} - {% if request.user.bonus >= payment.amount %} - Оплатить бонусами -

или купить онлайн

- {% else %} -

Для оплаты части стоимости вы можете использовать бонусы

- - {% endif %} + {% if school or gift_certificate %} + {% if request.user.bonus and not payment.bonus %} + {% if request.user.bonus >= payment.amount %} + Оплатить бонусами +

или купить онлайн

+ {% else %} +

Для оплаты части стоимости вы можете использовать бонусы

+ + {% endif %} + {% endif %} {% endif %}
{% include "./paymentwall_widget.html" %} @@ -24,6 +27,47 @@
{% endblock content %} -{% block foot %} +{% block foot_js %} + -{% endblock foot %} +{% endblock foot_js %} diff --git a/apps/payment/templates/payment/payment_success.html b/apps/payment/templates/payment/payment_success.html index c9b8d6fb..fbd311bf 100644 --- a/apps/payment/templates/payment/payment_success.html +++ b/apps/payment/templates/payment/payment_success.html @@ -1,8 +1,17 @@ -{% extends "templates/lilcity/index.html" %} {% load static %}{% load plural %} +{% extends "templates/lilcity/index.html" %} +{% load static %} +{% load rupluralize from plural %} + {% block content %}
+ {% if course %} +
Вы успешно приобрели курс!
+ + {% endif %} {% if school %}
Вы успешно приобрели доступ на {{ duration|rupluralize:"месяц,месяца,месяцев" }}!
@@ -15,19 +24,58 @@ ПЕРЕЙТИ В ЛАГЕРЬ
{% endif %} - {% if course %} -
Вы успешно приобрели курс!
- - {% endif %} {% if gift_certificate %}
Вы успешно приобрели подарочный сертификат!
+
Мы отправили письмо с сертификатом на вашу почту.
{% endif %}
{% endblock content %} + +{% block foot_js %} + +{% endblock foot_js %} diff --git a/apps/payment/views.py b/apps/payment/views.py index d9a4edc3..4806b761 100644 --- a/apps/payment/views.py +++ b/apps/payment/views.py @@ -4,7 +4,7 @@ import json import logging from datetime import timedelta -from urllib.parse import urlsplit +from urllib.parse import urlsplit, urlencode import datetime @@ -37,22 +37,28 @@ class DisallowedPingbackHost(Exception): @method_decorator(login_required, name='dispatch') class CourseBuySuccessView(TemplateView): - template_name = 'payment/course_payment_success.html' + template_name = 'payment/payment_success.html' - def get(self, request, pk=None, *args, **kwargs): - course = get_object_or_404(Course, pk=pk) - return self.render_to_response(context={'course': course}) + def get(self, request, payment_id, *args, **kwargs): + payment = CoursePayment.objects.get(pk=payment_id) + course = payment.course + return self.render_to_response(context={'course': course, 'payment': payment}) @method_decorator(login_required, name='dispatch') class SchoolBuySuccessView(TemplateView): template_name = 'payment/payment_success.html' - def get(self, request, pk=None, is_camp=False, *args, **kwargs): + def get(self, request, payment_id, is_camp=False, *args, **kwargs): + if is_camp: + payment = DrawingCampPayment.objects.get(pk=payment_id) + else: + payment = SchoolPayment.objects.get(pk=payment_id) context = { 'duration': request.GET.get('duration'), 'camp': is_camp, - 'school': not is_camp + 'school': not is_camp, + 'payment': payment, } return self.render_to_response(context=context) @@ -93,7 +99,7 @@ class CourseBuyView(TemplateView): course_payment.bonus = bonus course_payment.save() if course_payment.is_paid(): - return redirect(reverse_lazy('course_payment_success', args=[course.id])) + return redirect(reverse_lazy('course_payment_success', args=[course_payment.id])) product = Product( f'course_{course_payment.id}', course_payment.amount, @@ -110,7 +116,7 @@ class CourseBuyView(TemplateView): 'evaluation': 1, 'demo': 1, 'test_mode': 1, - 'success_url': host + str(reverse_lazy('course_payment_success', args=[course.id])), + 'success_url': host + str(reverse_lazy('course_payment_success', args=[course_payment.id])), 'failure_url': host + str(reverse_lazy('payment-error')), } ) @@ -118,7 +124,11 @@ class CourseBuyView(TemplateView): if request.user_agent.is_mobile: attrs['width'] = '100%' attrs['height'] = '600' - return self.render_to_response(context={'widget': widget.get_html_code(attrs)}) + return self.render_to_response(context={ + 'widget': widget.get_html_code(attrs), + 'payment': course_payment, + 'course': course, + }) @method_decorator(login_required, name='dispatch') @@ -159,7 +169,7 @@ class SchoolBuyView(TemplateView): school_payment.bonus = bonus school_payment.save() if school_payment.is_paid(): - return redirect('%s?duration=%s' % (str(reverse_lazy('payment-success')), duration)) + return redirect('%s?duration=%s' % (str(reverse_lazy('payment-success', args=[school_payment.id])), duration)) if payment_id and school_payment.bonus and not use_bonuses: bonus = school_payment.bonus school_payment.amount += school_payment.bonus @@ -181,7 +191,7 @@ class SchoolBuyView(TemplateView): 'evaluation': 1, 'demo': 1, 'test_mode': 1, - 'success_url': host + str(reverse_lazy('payment-success')) + '?duration=%s' % duration, + 'success_url': host + str(reverse_lazy('payment-success', args=[school_payment.id])) + '?duration=%s' % duration, 'failure_url': host + str(reverse_lazy('payment-error')), } ) @@ -241,7 +251,7 @@ class DrawingCampBuyView(TemplateView): camp_payment.bonus = bonus camp_payment.save() if camp_payment.is_paid(): - return redirect(reverse_lazy('camp-payment-success')) + return redirect(reverse_lazy('camp-payment-success', args=[camp_payment.id])) product = Product( f'drawing_camp_{camp_payment.id}', camp_payment.amount, @@ -258,7 +268,7 @@ class DrawingCampBuyView(TemplateView): 'evaluation': 1, 'demo': 1, 'test_mode': 1, - 'success_url': host + str(reverse_lazy('camp-payment-success')), + 'success_url': host + str(reverse_lazy('camp-payment-success', args=[camp_payment.id])), 'failure_url': host + str(reverse_lazy('payment-error')), } ) @@ -266,7 +276,11 @@ class DrawingCampBuyView(TemplateView): if request.user_agent.is_mobile: attrs['width'] = '100%' attrs['height'] = '600' - return self.render_to_response(context={'widget': widget.get_html_code(attrs)}) + return self.render_to_response(context={ + 'widget': widget.get_html_code(attrs), + 'payment': camp_payment, + 'camp': True, + }) @method_decorator(csrf_exempt, name='dispatch') @@ -427,10 +441,25 @@ class GiftCertificateBuyView(TemplateView): def get(self, request, pk, *args, **kwargs): gift_certificate = get_object_or_404(GiftCertificate, pk=pk) roistat_visit = request.COOKIES.get('roistat_visit', None) + use_bonuses = request.GET.get('use_bonuses') gift_certificate_payment = GiftCertificatePayment.objects.create( user=request.user, gift_certificate=gift_certificate, roistat_visit=roistat_visit,) + if use_bonuses and request.user.bonus: + if request.user.bonus >= gift_certificate_payment.amount: + bonus = UserBonus.objects.create(amount=-gift_certificate_payment.amount, user=request.user, + payment=gift_certificate_payment) + gift_certificate_payment.amount = 0 + gift_certificate_payment.status = Pingback.PINGBACK_TYPE_REGULAR + else: + bonus = UserBonus.objects.create(amount=-request.user.bonus, user=request.user, + payment=gift_certificate_payment) + gift_certificate_payment.amount -= request.user.bonus + gift_certificate_payment.bonus = bonus + gift_certificate_payment.save() + if gift_certificate_payment.is_paid(): + return redirect(reverse_lazy('gift-certificate-payment-success', args=[gift_certificate_payment.id])) context = self.get_context_data(**kwargs) product = Product( f'gift_certificate_{gift_certificate_payment.id}', @@ -458,19 +487,24 @@ class GiftCertificateBuyView(TemplateView): attrs['width'] = '100%' attrs['height'] = '600' context['widget'] = widget.get_html_code(attrs) + context['payment'] = gift_certificate_payment + context['gift_certificate'] = gift_certificate return self.render_to_response(context) @method_decorator(login_required, name='dispatch') class GiftCertificateBuySuccessView(TemplateView): - template_name = 'payment/gift_certificate_payment_success.html' + template_name = 'payment/payment_success.html' - def get(self, request, payment_id=None, *args, **kwargs): + def get(self, request, payment_id, *args, **kwargs): try: - GiftCertificatePayment.objects.get(id=payment_id) + payment = GiftCertificatePayment.objects.get(id=payment_id) except: raise Http404() - return self.render_to_response(context={'gift_certificate': True}) + return self.render_to_response(context={ + 'gift_certificate': payment.gift_certificate, + 'payment': payment, + }) @method_decorator(login_required, name='dispatch') diff --git a/project/templates/blocks/lil_store_js.html b/project/templates/blocks/lil_store_js.html index e3f9ede4..8bd16825 100644 --- a/project/templates/blocks/lil_store_js.html +++ b/project/templates/blocks/lil_store_js.html @@ -22,11 +22,11 @@ }, components: {}, urls: { - course: /\/course\/\d+\/, + course: /course\/\w+\/?$/, courseBuy: /course\/\d+\/checkout/, - courseBuySuccess: "{% url 'course_payment_success' %}", + courseBuySuccess: /payments\/course\/\d+\/success/, courses: "{% url 'courses' %}", - courseEdit: /\/course\/\d+\/edit/, + courseEdit: /course\/\d+\/edit/, courseCreate: "{% url 'course_create' %}", userProfileEdit: "{% url 'user-edit-profile' %}", userProfile: "{% url 'user-profile' %}", @@ -36,13 +36,14 @@ userGalleryEdit: "{% url 'user-gallery-edit' %}", school: "{% url 'school:school' %}", schoolBuy: "{% url 'school-checkout' %}", - schoolBuySuccess: "{% url 'payment-success' %}", + schoolBuySuccess: /payments\/school\/\d+\/success/, camp: "{% url 'school:drawing-camp' %}", campBuy: "{% url 'camp-checkout' %}", - campBuySuccess: "{% url 'camp-payment-success' %}", + campBuySuccess: /payments\/camp\/\d+\/success/, giftCertificates: "{% url 'gift-certificates' %}", giftCertificateBuy: /gift-certificate\/\d+\/checkout/, giftCertificateBuySuccess: /payments\/gift-certificate\/\d+\/success/, + prices: "{% url 'packages' %}", }, flags: { referrer: '{{ referrer.id|default:'' }}', @@ -56,7 +57,7 @@ urlPatternNames = [urlPatternNames]; } return urlPatternNames.filter(function(urlPatternName){ - return window.location.pathname.search(window.LIL_STORE.urls[urlPatternName]) > -1; + return window.LIL_STORE.urls[urlPatternName] && window.location.pathname.search(window.LIL_STORE.urls[urlPatternName]) > -1; }).length > 0; }, isIndexPage: window.location.pathname == '/', diff --git a/project/templates/lilcity/packages.html b/project/templates/lilcity/packages.html index 11e8ebd2..e6dda76e 100644 --- a/project/templates/lilcity/packages.html +++ b/project/templates/lilcity/packages.html @@ -38,6 +38,7 @@ {% if user.is_authenticated %} href="{% url 'school-checkout' %}?duration={{ package.duration }}" + data-package="{{ package.id }}" data-duration="{{ package.duration }}" data-price="{{ package.price|floatformat:'0' }}" {% else %} href="#" data-popup=".js-popup-auth" {% endif %} diff --git a/project/urls.py b/project/urls.py index 54415f98..dfb1514e 100644 --- a/project/urls.py +++ b/project/urls.py @@ -64,9 +64,9 @@ urlpatterns = [ path('lesson//comment', lessoncomment, name='lessoncomment'), path('payments/ping', PaymentwallCallbackView.as_view(), name='payment-ping'), path('paymentwall/pingback', PaymentwallCallbackView.as_view(), name='payment-ping-second'), - path('payments/course//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', + path('payments/course//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'), diff --git a/web/src/js/app.js b/web/src/js/app.js index a59403d6..bdf00d96 100644 --- a/web/src/js/app.js +++ b/web/src/js/app.js @@ -17,6 +17,7 @@ import "./modules/comments"; import "./modules/password-show"; import "./modules/notification"; import "./modules/mixpanel"; +import "./modules/gtag"; import "../sass/app.sass"; diff --git a/web/src/js/modules/gtag.js b/web/src/js/modules/gtag.js index 42ae4ba1..2cb8c273 100644 --- a/web/src/js/modules/gtag.js +++ b/web/src/js/modules/gtag.js @@ -1,12 +1,94 @@ import $ from 'jquery'; $(document).ready(function () { - if(window.LIL_STORE.urlIs(window.LIL_STORE.urls.course)){ + if(! window.LIL_STORE.user.id){ + return; + } + + if(window.LIL_STORE.urlIs(['courseBuy', 'schoolBuy', 'campBuy', 'giftCertificateBuy'])){ + if(window.LIL_STORE.urlIs(['schoolBuy', 'giftCertificateBuy'])){ + const $useBonuses = $('#use-bonuses-checkbox'); + $useBonuses.find('.switch__content').click(() => { + window.gtag('event', 'set_checkout_option', { + "checkout_step": 1, + "checkout_option": "use_bonuses", + "value": +!$useBonuses.find('input').prop('checked'), + }); + }); + $('#pay-with-bonuses').click(() => { + window.gtag('event', 'set_checkout_option', { + "checkout_step": 1, + "checkout_option": "use_bonuses", + "value": 1, + }); + }) + } + window.gtag('event', 'checkout_progress', { + "items": [window.LIL_STORE.data.gtagProduct], + }); + window.gtag('event', 'purchase', window.LIL_STORE.data.gtagTransaction); + } + + if(window.LIL_STORE.urlIs(['courseBuySuccess', 'schoolBuySuccess', 'campBuySuccess', 'giftCertificateBuySuccess'])){ + window.gtag('event', 'checkout_progress', { + "items": [window.LIL_STORE.data.gtagProduct], + }); + window.gtag('event', 'purchase', window.LIL_STORE.data.gtagTransaction); + } + + if(window.LIL_STORE.urlIs('course')){ const $btn = $('[data-popup=".js-popup-course-buy"]'); $btn.click(() => { window.gtag('event', 'begin_checkout', { "items": [window.LIL_STORE.data.gtagProduct], - "coupon": "" + }); + }); + const $popup = $('.js-popup-course-buy'); + const $useBonusesSwitch = $popup.find('.buy__bonuses .switch__content'); + const $useBonusesInput = $popup.find('.buy__bonuses input'); + $useBonusesSwitch.click(() => { + window.gtag('event', 'set_checkout_option', { + "checkout_step": 1, + "checkout_option": "use_bonuses", + "value": +!$useBonusesInput.prop('checked'), + }); + }); + const $buyBtn = $popup.find('.buy__btn'); + $buyBtn.click(() => { + window.gtag('event', 'checkout_progress', { + "items": [window.LIL_STORE.data.gtagProduct], + }); + }); + } + + if(window.LIL_STORE.urlIs('prices')){ + const $btns = $('.package__btn'); + $btns.click(function () { + const $this = $(this); + window.gtag('event', 'begin_checkout', { + "items": [{ + id: $this.data('package'), + name: 'Подписка на ' + +$this.data('duration') + ' месяцев', + category: 'package', + quantity: 1, + price: +$this.data('price'), + }], + }); + }) + } + + if(window.LIL_STORE.urlIs('giftCertificates')){ + const $btns = $('.gift-certificates__buy-btn'); + $btns.click(function () { + const $this = $(this); + window.gtag('event', 'begin_checkout', { + "items": [{ + id: $this.data('gift-certificate'), + name: 'Подарочный сертификат на ' + +$this.data('price') + ' руб', + category: 'gift-certificate', + quantity: 1, + price: +$this.data('price'), + }], }); }); }