From d7c1f136c4d946c615536fe1fb45da08f754713d Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 25 Dec 2017 16:02:30 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B3=D1=80=D0=B0=D0=BD=D0=B8=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BD=D0=B0=20=D0=B6=D1=83=D1=80?= =?UTF-8?q?=D0=BD=D0=B0=D0=BB=D1=8B=20(=D1=82=D0=B5=D0=BC,=20=D1=83=D1=80?= =?UTF-8?q?=D0=BE=D0=BA=D0=BE=D0=B2,=20=D0=BA=D1=83=D1=80=D1=81=D0=BE?= =?UTF-8?q?=D0=B2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- access/serializers.py | 2 +- access/views.py | 43 ++--- course_service/courses/views.py | 3 +- csv/load_bills.py | 55 +++--- finance/migrations/0001_initial.py | 2 +- finance/migrations/0002_auto_20171225_1142.py | 20 +++ finance/models.py | 2 +- finance/serializers.py | 5 - finance/signals.py | 158 +++++++++--------- 9 files changed, 157 insertions(+), 133 deletions(-) create mode 100644 finance/migrations/0002_auto_20171225_1142.py diff --git a/access/serializers.py b/access/serializers.py index 97e455c..e62c2f6 100644 --- a/access/serializers.py +++ b/access/serializers.py @@ -109,7 +109,7 @@ class UserSearchSerializer(serializers.ModelSerializer): @staticmethod def get_phone(self): - return self.account.phone + return None if self.account.phone is None else self.account.phone.raw_input @staticmethod def get_pay(self): diff --git a/access/views.py b/access/views.py index 169c613..b72f3de 100644 --- a/access/views.py +++ b/access/views.py @@ -12,9 +12,8 @@ from rest_framework.renderers import JSONRenderer from rest_framework.response import Response from rest_framework.views import APIView -from access.models.other import Invite, Progress, ResetPassword -from access.serializers import UserSelfSerializer, UserSearchSerializer -from course_service.courses.models import Vertex +from access.models.other import Invite, Progress, ResetPassword, PivotProgressVertex +from access.serializers import UserSelfSerializer, UserSearchSerializer, PivotProgressSerializer class TeacherListView(APIView): @@ -231,10 +230,6 @@ class LogoutView(APIView): class UpdateProgress(APIView): - """ - Переводит ученика на следующую стадию прохождения курса - Запрос идёт синхронно возвращает id нового объекта прогресса - """ renderer_classes = (JSONRenderer,) @staticmethod @@ -242,23 +237,31 @@ class UpdateProgress(APIView): """ На вход обязательно передаётся параметр id (id узла). """ - pk = int(request.JSON.get('id')) - res_403 = Response('Permission denied', status=403) - + token = request.JSON.get('token', None) + course = request.JSON.get('slug', None) + if token is None or course is None: + return Response('Не передан слаг курса или токен урока', status=400) try: - vertex = Vertex.objects.get(id=pk) - except Vertex.DoesNotExist: - return Response("Объект не найден", status=404) + p = Progress.objects.get(user=request.user, course=course) + try: + pv = PivotProgressVertex.objects.get( + progress=p, + vertex=token, + ) - if vertex.content_type.model == 'task': - return res_403 + except PivotProgressVertex.DoesNotExist: + pv = PivotProgressVertex.objects.create( + date=datetime.datetime.now(), + teacher=p.teacher, + progress=p, + vertex=token, + ) + pv.status = 2 + pv.save() + return Response(PivotProgressSerializer(pv).data, status=200) - try: - progress = Progress.objects.get(user=request.user, course=vertex.course) - progress.add_vertex(vertex) - return Response(status=204) except Progress.DoesNotExist: - return res_403 + return Response('Не найден прогресс по заданным параметрам', status=404) class UserGuardView(APIView): diff --git a/course_service/courses/views.py b/course_service/courses/views.py index 033fa63..75f95b3 100644 --- a/course_service/courses/views.py +++ b/course_service/courses/views.py @@ -37,7 +37,6 @@ class VertexDetail(APIView): @staticmethod def get(request, token): - status = int(request.GET.get('status', '200')) try: vertex = Vertex.objects.get(token=token) @@ -61,4 +60,4 @@ class VertexDetail(APIView): # except Thread.DoesNotExist or Vertex.DoesNotExist: # res['next'] = MiniVertexSerializer(vertex.get_next(vertex.course.route)).data - return Response(res, status=200) if status == 200 else Response(status=204) + return Response(res, status=200) diff --git a/csv/load_bills.py b/csv/load_bills.py index e0201ab..e5c7427 100644 --- a/csv/load_bills.py +++ b/csv/load_bills.py @@ -1,4 +1,7 @@ import csv +import random +import string + import django import os import sys @@ -43,33 +46,37 @@ if __name__ == '__main__': bill_kwarg['comment'] = row.pop('comment', None) bill_kwarg['description'] = row.pop('description', None) + try: bill = Bill.objects.create(**bill_kwarg) - method = row.pop('bill_method', None) - try: - price = int(row.pop('price', None)) - except ValueError: - price = None + except IntegrityError: + pass + method = row.pop('bill_method', None) + try: + price = int(row.pop('price', None)) + except ValueError: + price = None - try: - real_price = int(row.pop('real_price', None)) - except ValueError: - real_price = None + try: + real_price = int(row.pop('real_price', None)) + except ValueError: + real_price = None - inv = Invoice.objects.create(bill=bill, method=method, price=price, real_price=real_price, **row) - inv.date = row['date'] - inv.save() + key = row.pop('key', None) + if not key: + key = ''.join(random.choice(string.ascii_letters) for x in range(16)) - if method == 'Y' and not row['status'] == 'W': - row['yandex_pay'], _is_create = Payment.objects.get_or_create( - order_amount=price, - order_number=inv.id, - customer_number=bill.user.id, - user=bill.user, - cps_email=bill.user.email, - shop_amount=real_price, - status='Processed' if 'P' else ('Success' if 'F' else 'Fail') - ) + inv = Invoice.objects.create(bill=bill, method=method, price=price, real_price=real_price, key=key, **row) + inv.date = row['date'] + inv.save() - except IntegrityError: - pass \ No newline at end of file + if method == 'Y' and not row['status'] == 'W' and price: + row['yandex_pay'], _is_create = Payment.objects.get_or_create( + order_amount=price, + order_number=inv.id, + customer_number=bill.user.id, + user=bill.user, + cps_email=bill.user.email, + shop_amount=real_price, + status='Processed' if 'P' else ('Success' if 'F' else 'Fail') + ) \ No newline at end of file diff --git a/finance/migrations/0001_initial.py b/finance/migrations/0001_initial.py index a868bf8..d500563 100644 --- a/finance/migrations/0001_initial.py +++ b/finance/migrations/0001_initial.py @@ -13,7 +13,7 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('yandex_money', '0002_auto_20171128_1150'), + ('yandex_money', '0001_initial'), ] operations = [ diff --git a/finance/migrations/0002_auto_20171225_1142.py b/finance/migrations/0002_auto_20171225_1142.py new file mode 100644 index 0000000..b5199c6 --- /dev/null +++ b/finance/migrations/0002_auto_20171225_1142.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2017-12-25 11:42 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('finance', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='invoice', + name='price', + field=models.IntegerField(blank=True, editable=False, null=True, verbose_name='Сумма'), + ), + ] diff --git a/finance/models.py b/finance/models.py index 6ecb33b..fcdf0e1 100755 --- a/finance/models.py +++ b/finance/models.py @@ -43,7 +43,7 @@ class Invoice(models.Model): ('C', 'Отклонен'), ) status = models.CharField(verbose_name='Статус', max_length=1, default='W', choices=BILL_STATUSES) - price = models.IntegerField(verbose_name='Сумма', editable=False) + price = models.IntegerField(verbose_name='Сумма', editable=False, null=True, blank=True) real_price = models.IntegerField(verbose_name='Полученная сумма', null=True, blank=True, help_text='Сумма, минус комиссия', editable=False) method = models.CharField(verbose_name='Способ оплаты', max_length=2, default='Y', choices=BILL_METHOD) diff --git a/finance/serializers.py b/finance/serializers.py index 518be1b..0f3d735 100644 --- a/finance/serializers.py +++ b/finance/serializers.py @@ -6,7 +6,6 @@ from finance.models import Bill, Invoice class BillSerializer(serializers.ModelSerializer): opener = serializers.SerializerMethodField() user = serializers.SerializerMethodField() - course = serializers.SerializerMethodField() invoices = serializers.SerializerMethodField() class Meta: @@ -17,10 +16,6 @@ class BillSerializer(serializers.ModelSerializer): def get_user(self): return self.user.email - @staticmethod - def get_course(self): - return self.course.title - @staticmethod def get_invoices(self): return [InvoiceSerializer(i).data for i in self.invoice_set.all()] diff --git a/finance/signals.py b/finance/signals.py index 2010d64..5082a19 100644 --- a/finance/signals.py +++ b/finance/signals.py @@ -1,79 +1,79 @@ -from django.core.mail import EmailMessage -from django.db.models.signals import pre_save, post_save -from django.dispatch import receiver -from yandex_money.models import Payment - -from finance.models import Invoice -from access.models.other import Progress -from course_service.maps.api import OutApiRoute - -api = OutApiRoute - - -@receiver(pre_save, sender=Invoice) -def invoice_signal(instance, **kwargs): - """Отправка сообщения после сохранения платежа""" - if instance.yandex_pay and instance.method == 'Y' and instance.status == 'P': - msg = EmailMessage( - 'Вам выставлен новый счёт', - '''Вам выставлен счёт, для оплаты перейдите по ссылке - https://go.skillbox.ru/api/v1/finance/payment/%s/''' % instance.yandex_pay.id, - 'robo@skillbox.ru', - [instance.yandex_pay.cps_email], - [instance.bill.opener.email], - reply_to=[instance.bill.opener.email], - ) - msg.send() - - if instance.status == 'F': - if instance.is_open: - Progress.objects.get_or_create( - route=instance.bill.route, - user=instance.bill.user, - ) - msg = EmailMessage( - 'Ваш платёж прошёл успешно', - '''Вам открыт доступ к курсу "%s", вы можете перейти по ссылке и - ознакомиться с материалами https://go.skillbox.ru/course/%s''' - % (api.get_route(instance.bill.route).name, api.get_route(instance.bill.route).course.slug), - 'robo@skillbox.ru', - [instance.bill.user.email], - cc=[instance.bill.opener.email], - reply_to=[instance.bill.opener.email], - ) - else: - msg = EmailMessage( - 'Ваш платёж прошёл успешно', - '''Курс "%s" был забронирован''' % instance.bill.course.title, - 'robo@skillbox.ru', - [instance.yandex_pay.cps_email], - cc=[instance.bill.opener.email], - reply_to=[instance.bill.opener.email], - ) - msg.send() - - if instance.status == 'C': - msg = EmailMessage( - 'Ошибка платежа!' - """Внимание не прошёл платёж пользавателю %s, - по курсу "%s" ID платежа: %s. Если не получается - решить проблему самостоятельно, ответьте на это письмо, - постарайтесь подробно описать последовательность действий, - которая привела к ошибке""" - % (instance.bill.user.get_full_name(), api.get_route(instance.bill.route).course.title, instance.id), - instance.bill.opener.email, - reply_to=["it@skillbox.ru"] - ) - msg.send() - - -@receiver(post_save, sender=Payment) -def access_pay(instance, **kwargs): - if instance.status == 'success': - instance.invoice.status = "F" - instance.invoice.real_price = instance.shop_amount - instance.invoice.save() - - if instance.status == 'fail': - instance.invoice.status = "C" - instance.invoice.save() +# from django.core.mail import EmailMessage +# from django.db.models.signals import pre_save, post_save +# from django.dispatch import receiver +# from yandex_money.models import Payment +# +# from finance.models import Invoice +# from access.models.other import Progress +# from course_service.maps.api import OutApiRoute +# +# api = OutApiRoute +# +# +# @receiver(pre_save, sender=Invoice) +# def invoice_signal(instance, **kwargs): +# """Отправка сообщения после сохранения платежа""" +# if instance.yandex_pay and instance.method == 'Y' and instance.status == 'P': +# msg = EmailMessage( +# 'Вам выставлен новый счёт', +# '''Вам выставлен счёт, для оплаты перейдите по ссылке +# https://go.skillbox.ru/api/v1/finance/payment/%s/''' % instance.yandex_pay.id, +# 'robo@skillbox.ru', +# [instance.yandex_pay.cps_email], +# [instance.bill.opener.email], +# reply_to=[instance.bill.opener.email], +# ) +# msg.send() +# +# if instance.status == 'F': +# if instance.is_open: +# Progress.objects.get_or_create( +# route=instance.bill.route, +# user=instance.bill.user, +# ) +# msg = EmailMessage( +# 'Ваш платёж прошёл успешно', +# '''Вам открыт доступ к курсу "%s", вы можете перейти по ссылке и +# ознакомиться с материалами https://go.skillbox.ru/course/%s''' +# % (api.get_route(instance.bill.route).name, api.get_route(instance.bill.route).course.slug), +# 'robo@skillbox.ru', +# [instance.bill.user.email], +# cc=[instance.bill.opener.email], +# reply_to=[instance.bill.opener.email], +# ) +# else: +# msg = EmailMessage( +# 'Ваш платёж прошёл успешно', +# '''Курс "%s" был забронирован''' % instance.bill.course.title, +# 'robo@skillbox.ru', +# [instance.yandex_pay.cps_email], +# cc=[instance.bill.opener.email], +# reply_to=[instance.bill.opener.email], +# ) +# msg.send() +# +# if instance.status == 'C': +# msg = EmailMessage( +# 'Ошибка платежа!' +# """Внимание не прошёл платёж пользавателю %s, +# по курсу "%s" ID платежа: %s. Если не получается +# решить проблему самостоятельно, ответьте на это письмо, +# постарайтесь подробно описать последовательность действий, +# которая привела к ошибке""" +# % (instance.bill.user.get_full_name(), api.get_route(instance.bill.route).course.title, instance.id), +# instance.bill.opener.email, +# reply_to=["it@skillbox.ru"] +# ) +# msg.send() +# +# +# @receiver(post_save, sender=Payment) +# def access_pay(instance, **kwargs): +# if instance.status == 'success': +# instance.invoice.status = "F" +# instance.invoice.real_price = instance.shop_amount +# instance.invoice.save() +# +# if instance.status == 'fail': +# instance.invoice.status = "C" +# instance.invoice.save()