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 -*- # -*- coding: utf-8 -*-
from django.conf import settings from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.db import models from django.db import models
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
import json 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 lms.global_decorators import transaction_decorator
from library.models import Tags from library.models import Tags
from storage.models import Storage 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): class Course(models.Model):
COURSE_LEVEL = ( hidden = models.BooleanField(verbose_name='Видно только оплатившим', default=False)
('B', u'Базовый'), level = models.CharField(verbose_name='Уровень', choices=COURSE_LEVEL, default='B', max_length=3)
('A', u'Продвинутый'), slug = models.SlugField(max_length=255, blank=True, default='', unique=True, editable=False)
('E', u'Экспертный'), direction = models.SmallIntegerField(choices=COURSE_DIRECTION, verbose_name='Направление', null=True)
('B+A', u'Базовый + Продвинутый') mentors = models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name='Кураторы', blank=True,
)
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,
related_name='course_mentors') related_name='course_mentors')
public = models.BooleanField(verbose_name=u'Опубликовать', default=False) public = models.BooleanField(verbose_name='Опубликовать', default=False)
title = models.CharField(verbose_name=u"Заголовок", max_length=255) title = models.CharField(verbose_name="Заголовок", max_length=255)
description = models.TextField(verbose_name=u'Описание', blank=True) description = models.TextField(verbose_name='Описание', blank=True)
image = models.ImageField(verbose_name=u'Изображение', upload_to='course', blank=True) image = models.URLField(verbose_name='Изображение', blank=True, max_length=255)
big_image = models.ImageField(verbose_name=u'Большое изображение', upload_to='course', blank=True) big_image = models.URLField(verbose_name='Большое изображение', blank=True, max_length=255)
big_mobile_image = models.ImageField(verbose_name=u'Под мобилку', upload_to='course', blank=True, null=True, big_mobile_image = models.URLField(verbose_name='Под мобилку', blank=True, null=True,
help_text=u'Большая картинка для мобильной версии') help_text='Большая картинка для мобильной версии', max_length=255)
teachers = models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name=u'Преподаватели', teachers = models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name='Преподаватели',
related_name='course_teachers') related_name='course_teachers')
def __str__(self): def __str__(self):
@ -105,6 +155,8 @@ class Course(models.Model):
return vertex.get_previous(vertex_model_list) return vertex.get_previous(vertex_model_list)
objects = CourseManager()
class Meta: class Meta:
verbose_name = u"Курс" verbose_name = u"Курс"
verbose_name_plural = u"Курсы" verbose_name_plural = u"Курсы"
@ -235,7 +287,7 @@ class Vertex(models.Model):
raise ValueError('undefined model: ' + i) raise ValueError('undefined model: ' + i)
vertex_id = CourseMap.objects.get(course=self.course).get_next(self.id) 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: if vertex.content_type.model in vertex_model_list:
return vertex return vertex
@ -251,7 +303,7 @@ class Vertex(models.Model):
raise ValueError('undefined model: ' + i) raise ValueError('undefined model: ' + i)
vertex_id = CourseMap.objects.get(course=self.course).get_previous(self.id) 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: if vertex.content_type.model in vertex_model_list:
return vertex return vertex

@ -114,4 +114,4 @@ class CourseDetailSerializer(serializers.ModelSerializer):
@staticmethod @staticmethod
def get_teachers(self): 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,) renderer_classes = (JSONRenderer,)
status_code = 200 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): def get(self, request):
if request.user.is_authenticated() and request.user.is_staff: if request.user.is_authenticated() and request.user.is_staff:
return Response([CourseListSerializer(i).data for i in Course.objects.all()], self.status_code) 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) 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) 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) 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) blank=True, editable=False)
bill = models.ForeignKey(to=Bill, verbose_name="Связный счёт") 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 environ
amqp==2.2.2 amqp==2.2.2
billiard==3.5.0.3 billiard==3.5.0.3

Loading…
Cancel
Save