finance update

feature/fix_generate_pass
Andrey 8 years ago
parent 683e95de2d
commit 973752bd05
  1. 20
      courses/migrations/0004_auto_20171103_1409.py
  2. 20
      courses/migrations/0005_auto_20171103_1540.py
  3. 30
      courses/migrations/0006_auto_20171103_1623.py
  4. 30
      courses/migrations/0007_auto_20171103_1627.py
  5. 106
      courses/models.py
  6. 2
      courses/serializers.py
  7. 4
      courses/views.py
  8. 28
      csv/load_bills.py
  9. 2
      finance/models.py
  10. 19
      lms/tools.py
  11. 1
      requirements.txt
  12. 0
      static/css/system_messages.css
  13. 0
      static/css/tilda-grid.css

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-11-03 14:09
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('courses', '0003_auto_20171023_1037'),
]
operations = [
migrations.AlterField(
model_name='course',
name='slug',
field=models.SlugField(blank=True, default='', max_length=255, unique=True),
),
]

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-11-03 15:40
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('courses', '0004_auto_20171103_1409'),
]
operations = [
migrations.AlterField(
model_name='course',
name='slug',
field=models.SlugField(blank=True, default='', editable=False, max_length=255, unique=True),
),
]

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-11-03 16:23
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('courses', '0005_auto_20171103_1540'),
]
operations = [
migrations.AlterField(
model_name='course',
name='big_image',
field=models.ImageField(blank=True, max_length=255, upload_to='course', verbose_name='Большое изображение'),
),
migrations.AlterField(
model_name='course',
name='big_mobile_image',
field=models.ImageField(blank=True, help_text='Большая картинка для мобильной версии', max_length=255, null=True, upload_to='course', verbose_name='Под мобилку'),
),
migrations.AlterField(
model_name='course',
name='image',
field=models.ImageField(blank=True, max_length=255, upload_to='course', verbose_name='Изображение'),
),
]

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-11-03 16:27
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('courses', '0006_auto_20171103_1623'),
]
operations = [
migrations.AlterField(
model_name='course',
name='big_image',
field=models.URLField(blank=True, max_length=255, verbose_name='Большое изображение'),
),
migrations.AlterField(
model_name='course',
name='big_mobile_image',
field=models.URLField(blank=True, help_text='Большая картинка для мобильной версии', max_length=255, null=True, verbose_name='Под мобилку'),
),
migrations.AlterField(
model_name='course',
name='image',
field=models.URLField(blank=True, max_length=255, verbose_name='Изображение'),
),
]

@ -1,43 +1,93 @@
# -*- coding: utf-8 -*-
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.core.exceptions import ObjectDoesNotExist
import json
import unidecode
from django.template.defaultfilters import slugify
from lms.tools import decode_base64, get_real_name
from lms.global_decorators import transaction_decorator
from library.models import Tags
from storage.models import Storage
COURSE_LEVEL = (
('B', 'Базовый'),
('A', 'Продвинутый'),
('E', 'Экспертный'),
('B+A', 'Базовый + Продвинутый'),
)
COURSE_DIRECTION = (
(3, 'Бизнес'),
(2, 'Веб-дизайн'),
(1, 'Разработка'),
(4, 'Рисование'),
)
class CourseManager(models.Manager):
@transaction_decorator
def update_or_create_course(self, image=None, big_image=None, id=0,
big_mobile_image=None, mentors=None, slug=None,
teachers=None, level=None, direction=None, **kwargs):
slug = slug if slug else slugify(unidecode.unidecode(kwargs['title']))
if image:
kwargs['image'] = decode_base64(image, 'course/image%s.png' % slug)
if big_image:
kwargs['big_image'] = decode_base64(big_image, 'course/big_image%s.png' % slug)
if big_mobile_image:
kwargs['big_mobile_image'] = decode_base64(big_mobile_image, 'course/big_mobile_image%s.png' % slug)
if level:
kwargs['level'] = get_real_name(COURSE_LEVEL, level)
if direction:
kwargs['direction'] = get_real_name(COURSE_DIRECTION, direction)
try:
course = self.get(id=id)
for i in kwargs:
setattr(course, i, kwargs[i])
course.save()
except ObjectDoesNotExist:
kwargs['slug'] = slug
course = self.create(**kwargs)
CourseMap.objects.create(course=course)
if mentors:
for email in mentors:
course.mentors.add(get_user_model().objects.get(email=email))
if teachers:
for email in teachers:
course.teachers.add(get_user_model().objects.get(email=email))
return course
class Course(models.Model):
COURSE_LEVEL = (
('B', u'Базовый'),
('A', u'Продвинутый'),
('E', u'Экспертный'),
('B+A', u'Базовый + Продвинутый')
)
COURSE_DIRECTION = (
(3, 'Бизнес'),
(2, 'Веб-дизайн'),
(1, 'Разработка'),
(4, 'Рисование')
)
hidden = models.BooleanField(verbose_name=u'Видно только оплатившим', default=False)
level = models.CharField(verbose_name=u'Уровень', choices=COURSE_LEVEL, default='B', max_length=3)
slug = models.SlugField(max_length=255, editable=False, blank=True, default='', unique=True)
direction = models.SmallIntegerField(choices=COURSE_DIRECTION, verbose_name=u'Направление', null=True)
mentors = models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name=u'Кураторы', blank=True,
hidden = models.BooleanField(verbose_name='Видно только оплатившим', default=False)
level = models.CharField(verbose_name='Уровень', choices=COURSE_LEVEL, default='B', max_length=3)
slug = models.SlugField(max_length=255, blank=True, default='', unique=True, editable=False)
direction = models.SmallIntegerField(choices=COURSE_DIRECTION, verbose_name='Направление', null=True)
mentors = models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name='Кураторы', blank=True,
related_name='course_mentors')
public = models.BooleanField(verbose_name=u'Опубликовать', default=False)
title = models.CharField(verbose_name=u"Заголовок", max_length=255)
description = models.TextField(verbose_name=u'Описание', blank=True)
image = models.ImageField(verbose_name=u'Изображение', upload_to='course', blank=True)
big_image = models.ImageField(verbose_name=u'Большое изображение', upload_to='course', blank=True)
big_mobile_image = models.ImageField(verbose_name=u'Под мобилку', upload_to='course', blank=True, null=True,
help_text=u'Большая картинка для мобильной версии')
teachers = models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name=u'Преподаватели',
public = models.BooleanField(verbose_name='Опубликовать', default=False)
title = models.CharField(verbose_name="Заголовок", max_length=255)
description = models.TextField(verbose_name='Описание', blank=True)
image = models.URLField(verbose_name='Изображение', blank=True, max_length=255)
big_image = models.URLField(verbose_name='Большое изображение', blank=True, max_length=255)
big_mobile_image = models.URLField(verbose_name='Под мобилку', blank=True, null=True,
help_text='Большая картинка для мобильной версии', max_length=255)
teachers = models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name='Преподаватели',
related_name='course_teachers')
def __str__(self):
@ -105,6 +155,8 @@ class Course(models.Model):
return vertex.get_previous(vertex_model_list)
objects = CourseManager()
class Meta:
verbose_name = u"Курс"
verbose_name_plural = u"Курсы"
@ -235,7 +287,7 @@ class Vertex(models.Model):
raise ValueError('undefined model: ' + i)
vertex_id = CourseMap.objects.get(course=self.course).get_next(self.id)
vertex = Vertex.objects.get(id=int(vertex_id),)
vertex = Vertex.objects.get(id=int(vertex_id), )
if vertex.content_type.model in vertex_model_list:
return vertex
@ -251,7 +303,7 @@ class Vertex(models.Model):
raise ValueError('undefined model: ' + i)
vertex_id = CourseMap.objects.get(course=self.course).get_previous(self.id)
vertex = Vertex.objects.get(id=int(vertex_id),)
vertex = Vertex.objects.get(id=int(vertex_id), )
if vertex.content_type.model in vertex_model_list:
return vertex

@ -114,4 +114,4 @@ class CourseDetailSerializer(serializers.ModelSerializer):
@staticmethod
def get_teachers(self):
return [teacher.get_full_name() for teacher in self.teachers.all()]
return [teacher.email for teacher in self.teachers.all()]

@ -63,6 +63,10 @@ class CourseListView(APIView):
renderer_classes = (JSONRenderer,)
status_code = 200
def post(self, request):
course = Course.objects.update_or_create_course(**request.JSON.dict())
return Response(CourseDetailSerializer(course).data, status=self.status_code)
def get(self, request):
if request.user.is_authenticated() and request.user.is_staff:
return Response([CourseListSerializer(i).data for i in Course.objects.all()], self.status_code)

@ -0,0 +1,28 @@
import os, sys, django, csv
from django.contrib.auth import get_user_model
sys.path.append("../")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings")
django.setup()
from finance.models import Bill, Invoice
from courses.models import Course
if __name__ == '__main__':
Bill.objects.all().delete()
with open('./finance/bill.csv') as bill_csv:
bill_reader = csv.DictReader(bill_csv)
for row in bill_reader:
bill_kwarg = dict()
row = dict(row)
bill_kwarg['id'] = row.pop('id', None)
bill_kwarg['course'] = Course.objects.get(id=row.pop('course__id', None))
opener_id = row.pop('opener__id', None)
bill_kwarg['opener'] = get_user_model().objects.get(id=opener_id) if opener_id \
else get_user_model().objects.get(email="kate.gazukina@skillbox.ru")
bill_kwarg['user'] = get_user_model().objects.get(email=row.pop('user__email', None))
bill_kwarg['comment'] = row.pop('comment', None)
bill_kwarg['description'] = row.pop('description', None)
bill = Bill.objects.create(**bill_kwarg)
Invoice.objects.create(bill=bill, **row)

@ -45,7 +45,7 @@ class Invoice(models.Model):
bill_method = models.CharField(verbose_name='Способ оплаты', max_length=2, default='Y', choices=BILL_METHOD)
key = models.CharField(verbose_name='Ключ платежа', blank=True, max_length=255, default='', editable=False)
out_id = models.CharField(verbose_name='ID внешнего заказа', max_length=100, blank=True, default='', editable=False)
comment = models.TextField(verbose_name=u'Комментарий продавца', help_text=u'Будет показано пользователю',
comment = models.TextField(verbose_name='Комментарий продавца', help_text='Будет показано пользователю',
blank=True, editable=False)
bill = models.ForeignKey(to=Bill, verbose_name="Связный счёт")

@ -0,0 +1,19 @@
import base64
from django.conf import settings
def decode_base64(my_str, upload_to):
if "data:" in my_str:
my_str = my_str[my_str.index("base64,")+7:]
path = "%s/%s" % (settings.MEDIA_ROOT, upload_to)
url = "%s%s" % (settings.MEDIA_URL, upload_to)
with open(path, "wb") as fh:
fh.write(base64.b64decode(my_str))
return url
return my_str
def get_real_name(array, elem):
for i, j in array:
if i and (i == elem or j == elem):
return i

@ -1,3 +1,4 @@
unidecode
environ
amqp==2.2.2
billiard==3.5.0.3

Loading…
Cancel
Save