remotes/origin/hotfix/LIL-691
gzbender 7 years ago
parent 787d93945f
commit 75f46a1065
  1. 28
      apps/payment/models.py
  2. 30
      apps/payment/views.py
  3. 2
      apps/user/models.py
  4. 28
      apps/user/templates/user/bonus-history.html
  5. 26
      apps/user/templates/user/payment-history.html
  6. 2
      project/templates/blocks/lil_store_js.html
  7. 18
      project/templates/blocks/popup_auth.html
  8. 4
      web/src/js/modules/common.js
  9. 54
      web/src/sass/_common.sass

@ -103,6 +103,7 @@ class Payment(PolymorphicModel):
roistat_visit = models.PositiveIntegerField('Номер визита Roistat', null=True, editable=False)
created_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
bonus = models.ForeignKey('payment.UserBonus', null=True, on_delete=models.SET_NULL, related_name='purchase_payments')
objects = PaymentManger()
@ -111,6 +112,15 @@ class Payment(PolymorphicModel):
verbose_name_plural = 'Платежи'
ordering = ('created_at',)
@classmethod
def add_months(cls, sourcedate, months=1):
result = arrow.get(sourcedate, settings.TIME_ZONE).shift(months=months)
if months == 1:
if (sourcedate.month == 2 and sourcedate.day >= 28) or (sourcedate.day == 31 and result.day <= 30)\
or (sourcedate.month == 1 and sourcedate.day >= 29 and result.day == 28):
result = result.replace(day=1, month=result.month + 1)
return result.datetime
@classmethod
def calc_amount(cls, payment=None, user=None, course=None, weekdays=None):
if isinstance(payment, CoursePayment):
@ -134,7 +144,6 @@ class Payment(PolymorphicModel):
user=user,
date_start__lte=now().date(),
date_end__gte=now().date(),
add_days=False,
status__in=[
Pingback.PINGBACK_TYPE_REGULAR,
Pingback.PINGBACK_TYPE_GOODWILL,
@ -144,8 +153,8 @@ class Payment(PolymorphicModel):
school_schedules_purchased = school_payments.annotate(
joined_weekdays=Func(F('weekdays'), function='unnest', )
).values_list('joined_weekdays', flat=True).distinct()
weekdays = set(map(int, weekdays)) - set(school_schedules_purchased)
prev_school_payment = school_payments.last()
weekdays = list(set(map(int, weekdays)) - set(school_schedules_purchased))
prev_school_payment = school_payments.filter(add_days=False).last()
add_days = bool(prev_school_payment)
else:
add_days = False
@ -173,6 +182,7 @@ class Payment(PolymorphicModel):
'referral_bonus': referral_bonus,
'referrer_bonus': referrer_bonus,
'discount': discount,
'weekdays': weekdays,
}
def calc_commission(self):
@ -197,10 +207,14 @@ class Payment(PolymorphicModel):
def save(self, *args, **kwargs):
amount_data = Payment.calc_amount(payment=self)
self.amount = amount_data.get('amount')
if isinstance(self, SchoolPayment):
self.weekdays = amount_data.get('weekdays')
super().save(*args, **kwargs)
paid = self.status in [Pingback.PINGBACK_TYPE_REGULAR, Pingback.PINGBACK_TYPE_GOODWILL,
Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,]
if isinstance(self, CoursePayment):
author_balance = getattr(self, 'authorbalance', None)
if not author_balance:
if not author_balance and paid:
AuthorBalance.objects.create(
author=self.course.author,
amount=self.amount,
@ -210,9 +224,7 @@ class Payment(PolymorphicModel):
author_balance.amount = self.amount
author_balance.save()
# Если юзер реферал и нет платежа, где применялась скидка
if hasattr(self.user, 'referral') and not self.user.referral.payment\
and self.status in [Pingback.PINGBACK_TYPE_REGULAR, Pingback.PINGBACK_TYPE_GOODWILL,
Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,]:
if hasattr(self.user, 'referral') and not self.user.referral.payment and paid:
# Платеж - как сигнал, что скидка применилась
self.user.referral.payment = self
self.user.referral.save()
@ -258,3 +270,5 @@ class UserBonus(models.Model):
referral = models.ForeignKey('user.Referral', on_delete=models.SET_NULL, null=True)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ('created_at',)

@ -25,7 +25,7 @@ from apps.course.models import Course
from apps.school.models import SchoolSchedule
from apps.payment.tasks import transaction_to_mixpanel, product_payment_to_mixpanel, transaction_to_roistat
from .models import AuthorBalance, CoursePayment, SchoolPayment
from .models import AuthorBalance, CoursePayment, SchoolPayment, Payment, UserBonus
logger = logging.getLogger('django')
@ -118,7 +118,7 @@ class SchoolBuyView(TemplateView):
Pingback.PINGBACK_TYPE_GOODWILL,
Pingback.PINGBACK_TYPE_RISK_REVIEWED_ACCEPTED,
],
).first() # ??? first?
).last()
add_days = bool(prev_school_payment)
if add_days:
school_payment = SchoolPayment.objects.create(
@ -129,6 +129,7 @@ class SchoolBuyView(TemplateView):
add_days=True,
roistat_visit=roistat_visit,
)
# Если произойдет ошибка и оплату бонусами повторят еще раз на те же дни, то вернет ошибку
if school_payment.amount <= 0:
messages.error(request, 'Выбранные дни отсутствуют в оставшемся периоде подписки')
return redirect(reverse_lazy('school:school'))
@ -138,6 +139,19 @@ class SchoolBuyView(TemplateView):
weekdays=weekdays,
roistat_visit=roistat_visit,
)
if use_bonuses:
if request.user.bonus >= school_payment.amount:
bonus = UserBonus.objects.create(amount=- school_payment.amount, user=request.user, payment=school_payment)
school_payment.status = Pingback.PINGBACK_TYPE_REGULAR
school_payment.bonus = bonus
if not add_days:
school_payment.date_start = now().date()
school_payment.date_end = Payment.add_months(school_payment.date_start)
school_payment.save()
return redirect(reverse_lazy('payment-success'))
else:
messages.error(request, 'Недостаточно бонусов для оплаты')
return redirect(reverse_lazy('school:school'))
product = Product(
f'school_{school_payment.id}',
school_payment.amount,
@ -163,14 +177,6 @@ class SchoolBuyView(TemplateView):
@method_decorator(csrf_exempt, name='dispatch')
class PaymentwallCallbackView(View):
def add_months(self, sourcedate, months=1):
result = arrow.get(sourcedate, settings.TIME_ZONE).shift(months=months)
if months == 1:
if (sourcedate.month == 2 and sourcedate.day >= 28) or (sourcedate.day == 31 and result.day <= 30)\
or (sourcedate.month == 1 and sourcedate.day >= 29 and result.day == 28):
result = result.replace(day=1, month=result.month + 1)
return result.datetime
def get_request_ip(self):
x_forwarded_for = self.request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
@ -234,10 +240,10 @@ class PaymentwallCallbackView(View):
date_end = school_payment.date_end
else:
date_start = arrow.get(school_payment.date_end, settings.TIME_ZONE).shift(days=1).datetime
date_end = self.add_months(date_start)
date_end = Payment.add_months(date_start)
else:
date_start = now().date()
date_end = self.add_months(date_start)
date_end = Payment.add_months(date_start)
payment.date_start = date_start
payment.date_end = date_end
if product_type_name == 'course':

@ -107,7 +107,7 @@ class User(AbstractUser):
@cached_property
def bonus(self):
return int(self.bonuses.aggregate(models.Sum('amount')).get('amount__sum')) or 0
return int(self.bonuses.aggregate(models.Sum('amount')).get('amount__sum') or 0)
@receiver(post_save, sender=User)

@ -23,25 +23,35 @@
</div>
<div class="section section_gray">
<div class="section__center center center_xs">
<div class="section__center center center_sm">
<div class="title title_sm">История бонусов</div>
<div class="transactions">
<div class="transactions transactions_bonuses">
<div class="transactions__wrap">
<div class="transactions__row">
<div class="transactions__cell transactions__product">Продукт</div>
<div class="transactions__cell transactions__amount">Сумма покупки</div>
<div class="transactions__cell transactions__user">Реферал</div>
<div class="transactions__cell transactions__amount">Сумма бонусов</div>
</div>
{% for bonus in bonuses %}
<div class="transactions__row">
{% with payment=bonus.payment %}
{% if payment.course %}
<div class="transactions__cell">Курс. {{ payment.course.title }}</div>
<div class="transactions__cell transactions__product">Курс. {{ payment.course.title }}</div>
{% else %}
<div class="transactions__cell">
<div class="transactions__cell transactions__product">
{% if request.user_agent.is_mobile %}
Школа. {% if payment.date_start and payment.date_end %}{{ payment.date_start|date:"" }} - {{ payment.date_end }}{% endif %}
{% else %}
Школа. {% if payment.date_start and payment.date_end %}{{ payment.date_start }} - {{ payment.date_end }}{% endif %}
{% endif %}
</div>
{% endif %}
<div class="transactions__cell">{{payment.amount }}</div>
{% if bonus.referral %}
<div class="transactions__cell"><a href="{% url 'user' pk=bonus.referral.referral.id %}">{{ bonus.referral.referral.get_full_name }}</a></div>
{% endif %}
<div class="transactions__cell">{{ bonus.amount|floatformat }}</div>
<div class="transactions__cell transactions__amount">{{payment.amount }}</div>
<div class="transactions__cell transactions__user">
{% if bonus.referral %}{{ bonus.referral.referral.get_full_name }}{% endif %}
</div>
<div class="transactions__cell transactions__amount">{{ bonus.amount|floatformat }}</div>
{% endwith %}
</div>
{% empty %}

@ -65,42 +65,42 @@
<div class="section section_gray">
<div class="section__center center center_xs">
<div class="title title_sm">История платежей</div>
<div class="transactions">
<div class="transactions transactions_payments">
<div class="transactions__wrap">
{% if request.user.payments.all.exists %}
{% for payment in request.user.payments.all %}
<div class="transactions__row">
{% if payment.course %}
<div class="transactions__cell">Курс. {{payment.course.title}}</div>
<div class="transactions__cell transactions__product">Курс. {{payment.course.title}}</div>
{% else %}
<div class="transactions__cell">
<div class="transactions__cell transactions__product">
Школа. {% if payment.date_start and payment.date_end %}{{ payment.date_start }} - {{ payment.date_end }}{% endif %}
</div>
{% endif %}
{% if payment.balance %}
<div class="transactions__cell">{{payment.balance.amount}}</div>
<div class="transactions__cell transactions__amount">{{payment.balance.amount}}</div>
{% else %}
<div class="transactions__cell">{{payment.amount}}</div>
<div class="transactions__cell transactions__amount">{{payment.amount}}</div>
{% endif %}
{% if payment.balance.type == 1 %}
<div class="transactions__cell">
<div class="transactions__cell transactions__status">
{% if payment.balance.status == 0 %}
<span class="transactions__cell__pending">Ожидается подтверждение выплаты</span>
<span class="transactions__status_pending">Ожидается подтверждение выплаты</span>
{% elif payment.balance.status == 1 %}
<span class="transactions__cell__success">Выплачено</span>
<span class="transactions__status_success">Выплачено</span>
{% else %}
<span class="transactions__cell__error">Выплата отменена</span>
<span class="transactions__status_error">Выплата отменена</span>
Причина: "{{ payment.balance.cause }}
{% endif %}
</div>
{% else %}
<div class="transactions__cell">
<div class="transactions__cell transactions__status">
{% if payment.is_deliverable %}
<span class="transactions__cell__success">Оплачено</span>
<span class="transactions__status_success">Оплачено</span>
{% elif payment.is_under_review %}
<span class="transactions__cell__pending">Ожидается подтверждение оплаты</span>
<span class="transactions__status_pending">Ожидается подтверждение оплаты</span>
{% else %}
<span class="transactions__cell__error">Ошибка оплаты</span>
<span class="transactions__status_error">Ошибка оплаты</span>
{% endif %}
</div>
{% endif %}

@ -8,7 +8,7 @@
id: '{{ request.user.id|default:'' }}',
},
flags: {
isReferralRegistration: '{{ is_referral_registration|yesno:"true,false" }}',
isReferralRegistration: {{ is_referral_registration|yesno:"true,false" }},
}
};
</script>

@ -1,5 +1,5 @@
{% load static %}
<div class="popup js-popup-auth {% if is_registration %}open visible{% endif %}">
<div class="popup js-popup-auth {% if is_referral_registration %}open visible{% endif %}">
<div class="popup__wrap js-popup-wrap">
<button class="popup__close js-popup-close">
<svg class="icon icon-close">
@ -10,13 +10,13 @@
<div class="auth js-auth">
<div class="auth__login js-auth-login">
<div class="auth__nav">
<a class="auth__type js-auth-type {% if not is_registration %}active{% endif %}" href="#">Войти</a>
<a class="auth__type js-auth-type {% if is_registration %}active{% endif %}" href="#">РЕГИСТРАЦИЯ</a>
<a class="auth__type js-auth-type {% if not is_referral_registration %}active{% endif %}" href="#">Войти</a>
<a class="auth__type js-auth-type {% if is_referral_registration %}active{% endif %}" href="#">РЕГИСТРАЦИЯ</a>
</div>
<div class="auth__body">
<form id="learner-auth-form" method="post" action="{% url 'lilcity:login' %}">
{% csrf_token %}
<div class="auth__tab js-auth-tab" {% if not is_registration %}style="display: block;"{% endif %}>
<div class="auth__tab js-auth-tab" {% if not is_referral_registration %}style="display: block;"{% endif %}>
<div class="auth__enter js-auth-enter">
<div id="learner-auth-field__username" class="auth__field field learner-auth-form__field">
<div class="field__label">ПОЧТА</div>
@ -63,17 +63,9 @@
</form>
<form id="learner-registration-form" method="post" action="{% url 'lilcity:registration-learner' %}">
{% csrf_token %}
<div class="auth__tab js-auth-tab" {% if is_registration %}style="display: block;"{% endif %}>
<div class="auth__tab js-auth-tab" {% if is_referral_registration %}style="display: block;"{% endif %}>
{% if referrer %}
<input type="hidden" name="referrer" value="{{ referrer.id }}">
<div style="margin: 0 0 20px;">
<a href="{% url 'user' referrer.id %}" target="_blank" style="
font-family: 'ProximaNova-Bold', serif;
font-size: 10px;
letter-spacing: 1px;
text-transform: uppercase;">
{{ referrer.get_full_name }}</a> дарит вам скидку 10% на первую покупку!
</div>
{% endif %}
<div class="auth__fieldset">
<div id="learner-registration-field__first-name" class="auth__field field learner-registration-form__field">

@ -42,7 +42,9 @@ $(document).ready(function () {
});
if(window.LIL_STORE.flags.isReferralRegistration && ! window.LIL_STORE.user.id){
$('.js-header-enter').click();
setTimeout(() => {
$('.js-header-enter').click();
});
}
});

@ -3213,31 +3213,41 @@ a.grey-link
&__cell
padding: 0 10px
font-size: 13px
&__success
&__product
+fb
font-size: 12px
text-transform: uppercase
letter-spacing: 2px
flex: 0 0 60%
+m
flex: 0 0 75%
&__amount
flex: 0 0 20%
text-align: right
+m
flex: 0 0 25%
&__status
flex: 0 0 20%
text-align: right
color: $green-light
+m
flex: 0 0 100%
&_success
color: $green
&__pending
&_pending
color: $gray
&__error
&_error
color: $pink
&:first-child
+fb
font-size: 12px
text-transform: uppercase
letter-spacing: 2px
flex: 0 0 60%
+m
flex: 0 0 75%
&:nth-child(2),
&:last-child
flex: 0 0 20%
text-align: right
&:nth-child(2)
+m
flex: 0 0 25%
&:last-child
color: $green-light
+m
flex: 0 0 100%
.transactions_bonuses .transactions
&__product
flex: 0 0 60%;
+m
flex: 0 0 40%;
&__amount
flex: 0 0 10%;
&__user
flex: 0 0 20%;
.empty
max-width: 300px

Loading…
Cancel
Save