Миграции курсов

feature/fix_generate_pass
Andrey 8 years ago
parent 98f3cbef63
commit 877b8d7015
  1. 36
      access/models.py
  2. 3
      courses/admin.py
  3. 37
      courses/migrations/0003_auto_20171023_1037.py
  4. 38
      courses/models.py
  5. 3
      courses/views.py
  6. 4
      finance/admin.py
  7. 58
      finance/models.py
  8. 4
      journals/admin.py
  9. 119
      journals/default_threads.py
  10. 37
      journals/migrations/0003_auto_20171023_1208.py
  11. 20
      journals/migrations/0004_auto_20171023_1234.py
  12. 10
      journals/models.py
  13. 1
      lms/admin.py

@ -1,6 +1,12 @@
# encoding=utf-8 # encoding=utf-8
import random import random
import string import string
import json
from celery.result import AsyncResult
from django.contrib.contenttypes.models import ContentType
from django_celery_results.models import TaskResult
from courses.models import Vertex, Course from courses.models import Vertex, Course
from storage.models import Storage from storage.models import Storage
from django.core.mail import send_mail from django.core.mail import send_mail
@ -14,6 +20,7 @@ from django.conf import settings
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from lms.global_decorators import transaction_decorator from lms.global_decorators import transaction_decorator
from journals.models import Journal, Thread, ACTION_CHOICES
class Invite(models.Model): class Invite(models.Model):
@ -79,7 +86,7 @@ class CustomUserManager(BaseUserManager):
email = self.normalize_email(email) email = self.normalize_email(email)
user = self.model(email=email, is_staff=is_staff, is_active=is_active, first_name=first_name, user = self.model(email=email, is_staff=is_staff, is_active=is_active, first_name=first_name,
id=self.last().id +1 if self.last() else 0, id=self.last().id + 1 if self.last() else 0,
is_superuser=is_superuser, date_joined=date_joined, last_login=last_login, **extra_fields) is_superuser=is_superuser, date_joined=date_joined, last_login=last_login, **extra_fields)
if not password: if not password:
@ -99,15 +106,20 @@ class CustomUserManager(BaseUserManager):
user.groups.add(Group.objects.get(name=group)) user.groups.add(Group.objects.get(name=group))
if is_send: if is_send:
invite = Invite.objects.create(owner=user, hash=''.join(random.choice(string.ascii_letters) for x in range(15))) invite = Invite.objects.create(owner=user,
send_mail( hash=''.join(random.choice(string.ascii_letters) for x in range(15)))
subject='Спасибо за регистрацию', body = {
message=''' "subject": 'Спасибо за регистрацию',
Вы были успешны зарегистрированны на портале go.skillbox.ru "message": '''
для подтверждения регистрации перейдите по ссылке Вы были успешны зарегистрированны на портале go.skillbox.ru
https://go.skillbox.ru/api/v1/users/registration/?hash=''' + invite.hash, для подтверждения регистрации перейдите по ссылке
from_email='robo@skillbox.ru', https://go.skillbox.ru/api/v1/users/registration/?hash=''' + invite.hash,
recipient_list=[user.email], "from_email": 'robo@skillbox.ru',
"recipient_list": [user.email],
}
tasks = send_mail(
**body
) )
return user return user
@ -132,8 +144,8 @@ class User(AbstractBaseUser, PermissionsMixin):
help_text='Определяет активен ли пользователь в системе. Снимите флаг, ' help_text='Определяет активен ли пользователь в системе. Снимите флаг, '
'вместо удаления пользователя.') 'вместо удаления пользователя.')
is_blocked = models.BooleanField(verbose_name='заблочен', default=False, is_blocked = models.BooleanField(verbose_name='заблочен', default=False,
help_text='Определяет заблокирован ли пользователь. Поставьте флаг, ' help_text='Определяет заблокирован ли пользователь. Поставьте флаг, '
'если знаете, что это нехороший человек.') 'если знаете, что это нехороший человек.')
objects = CustomUserManager() objects = CustomUserManager()

@ -1,7 +1,7 @@
from django.contrib import admin from django.contrib import admin
from courses.models import Course, Skills, Achievements, SkillJ,\ from courses.models import Course, Skills, Achievements, SkillJ,\
CourseMap, Topic, Task, Vertex, Diploma, Tutorial CourseMap, Topic, Task, Vertex, Diploma, Tutorial, DiplomaGen
admin.site.register(CourseMap) admin.site.register(CourseMap)
admin.site.register(Topic) admin.site.register(Topic)
@ -13,3 +13,4 @@ admin.site.register(Skills)
admin.site.register(Achievements) admin.site.register(Achievements)
admin.site.register(SkillJ) admin.site.register(SkillJ)
admin.site.register(Diploma) admin.site.register(Diploma)
admin.site.register(DiplomaGen)

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-10-23 10:37
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('courses', '0002_auto_20171019_1149'),
]
operations = [
migrations.CreateModel(
name='DiplomaGen',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('template', models.URLField(verbose_name='Путь до шаблона')),
('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.Course')),
],
options={
'verbose_name': 'Генератор дипломов',
'verbose_name_plural': 'Генераторы дипловов',
},
),
migrations.RemoveField(
model_name='diploma',
name='course',
),
migrations.AddField(
model_name='diploma',
name='template',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='courses.DiplomaGen', verbose_name='Использовать шаблон'),
),
]

@ -111,10 +111,10 @@ class Course(models.Model):
class Skills(models.Model): class Skills(models.Model):
title = models.CharField(verbose_name=u'Наименование', max_length=255) title = models.CharField(verbose_name='Наименование', max_length=255)
color = models.CharField(verbose_name=u'Цвет', max_length=255) color = models.CharField(verbose_name='Цвет', max_length=255)
icon = models.ImageField(verbose_name=u'Большая картинка', upload_to='skills', null=True, help_text='65x65') icon = models.ImageField(verbose_name='Большая картинка', upload_to='skills', null=True, help_text='65x65')
description = models.TextField(verbose_name=u'Описание', blank=True) description = models.TextField(verbose_name='Описание', blank=True)
def __str__(self): return '%s' % self.title def __str__(self): return '%s' % self.title
@ -124,14 +124,14 @@ class Skills(models.Model):
class SkillJ(models.Model): class SkillJ(models.Model):
skill = models.ForeignKey(to="Skills", verbose_name=u'Навык') skill = models.ForeignKey(to="Skills", verbose_name='Навык')
lesson = models.ForeignKey(to="Vertex", verbose_name=u'Урок') lesson = models.ForeignKey(to="Vertex", verbose_name='Урок')
def __str__(self): return '%s' % self.skill def __str__(self): return '%s' % self.skill
class Meta: class Meta:
verbose_name = u'Размер навыка' verbose_name = 'Размер навыка'
verbose_name_plural = u'Размеры навыков' verbose_name_plural = 'Размеры навыков'
class Achievements(models.Model): class Achievements(models.Model):
@ -143,17 +143,29 @@ class Achievements(models.Model):
return 'Студенту %s за курс %s' % (self.user.username, self.course.title) return 'Студенту %s за курс %s' % (self.user.username, self.course.title)
class Meta: class Meta:
verbose_name = u'Достижение' verbose_name = 'Достижение'
verbose_name_plural = u'Достижения' verbose_name_plural = 'Достижения'
class Diploma(models.Model): class DiplomaGen(models.Model):
icon = models.ImageField(verbose_name=u'Иконка', upload_to='diplomas')
course = models.ForeignKey(to=Course) course = models.ForeignKey(to=Course)
template = models.URLField(verbose_name="Путь до шаблона")
def __str__(self):
return 'Шаблон можно найти по адресу: %s, диплом выдаётся за курс %s' % (self.template, self.course.title)
class Meta:
verbose_name = 'Генератор дипломов'
verbose_name_plural = 'Генераторы дипловов'
class Diploma(models.Model):
icon = models.ImageField(verbose_name='Иконка', upload_to='diplomas')
template = models.ForeignKey(to=DiplomaGen, verbose_name='Использовать шаблон', blank=True, null=True)
user = models.ForeignKey(to=settings.AUTH_USER_MODEL) user = models.ForeignKey(to=settings.AUTH_USER_MODEL)
def __str__(self): def __str__(self):
return 'Студенту %s за курс %s' % (self.user.username, self.course.title) return 'Студенту %s за курс %s' % (self.user.username, self.template.course.title)
class Meta: class Meta:
verbose_name = 'Диплом' verbose_name = 'Диплом'

@ -6,7 +6,6 @@ from access.serializers import ExtraPrivilegeSerializer
from courses.models import Course, Vertex from courses.models import Course, Vertex
from access.models import Progress, ExtraPrivilege from access.models import Progress, ExtraPrivilege
from courses.serializers import CourseDetailSerializer, CourseListSerializer, VertexSerializer, CourseTreeSerializer from courses.serializers import CourseDetailSerializer, CourseListSerializer, VertexSerializer, CourseTreeSerializer
from finance.models import Bill
class TreeView(APIView): class TreeView(APIView):
@ -66,7 +65,7 @@ class CourseListView(APIView):
if course.public: if course.public:
course_serialize = CourseListSerializer(course).data course_serialize = CourseListSerializer(course).data
course_serialize['is_mine'] = False course_serialize['is_mine'] = False
if request.user.is_authenticated() and Bill.objects.filter(service__course=course, user=request.user, status='F').exists(): if request.user.is_authenticated() and Progress.objects.filter(course=course, user=request.user).exists():
course_serialize['is_mine'] = True course_serialize['is_mine'] = True
res.append(course_serialize) res.append(course_serialize)

@ -1,7 +1,7 @@
# coding=utf-8 # coding=utf-8
from django.contrib import admin from django.contrib import admin
from finance.models import Bill, Price from finance.models import Bill, Invoice
admin.site.register(Bill) admin.site.register(Bill)
admin.site.register(Price) admin.site.register(Invoice)

@ -4,33 +4,26 @@ from django.conf import settings
from courses.models import Course, Vertex from courses.models import Course, Vertex
class Price(models.Model): class Bill(models.Model):
# Цены course = models.ForeignKey(to=Course, verbose_name='Курс', blank=True, null=True)
public = models.BooleanField(verbose_name='Опубликовать', default=False) user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='Плательщик', related_name=u'bill_user')
title = models.CharField(verbose_name='Услуга', max_length=255, help_text=u'Будет показано пользователям') opener = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='Ответственный сотрудник', null=True)
cost = models.IntegerField(verbose_name='Цена') comment = models.TextField(verbose_name=u'Комментарий продавца', help_text=u'Будет показано пользователю',
course = models.ForeignKey(to=Course, verbose_name='Курс', null=True, blank=True) blank=True, editable=False)
vertexes = models.ManyToManyField(to=Vertex, verbose_name='Список всех узлов') description = models.TextField(verbose_name='Внутренняя заметка', default='')
description = models.TextField(verbose_name='Описание', help_text='Будет показано менеджерам')
by_time = models.IntegerField(verbose_name='Дней доступа', blank=True, null=True)
def __str__(self): def __str__(self):
return '%s / %s %s' % (self.course.title, self.title, self.cost) return '%s:%s %s' % (self.id, self.course, self.user)
def get_full_price(self):
return sum([i.price for i in self.invoice_set.all()])
class Meta: class Meta:
verbose_name = u'Услуга' verbose_name = 'Счет'
verbose_name_plural = u'Услуги' verbose_name_plural = 'Счета'
ordering = ['-id']
class Bill(models.Model): class Invoice(models.Model):
BILL_STATUSES = (
('W', 'Ожидание согласия'),
('P', 'На оплате'),
('F', 'Оплачен'),
('C', 'Отклонен'),
('H', 'Сгорел')
)
BILL_METHOD = ( BILL_METHOD = (
('C', 'Наличные'), ('C', 'Наличные'),
('H', 'JustClick'), ('H', 'JustClick'),
@ -38,26 +31,27 @@ class Bill(models.Model):
('S', 'SimplePay'), ('S', 'SimplePay'),
('Y', 'YandexKassa') ('Y', 'YandexKassa')
) )
BILL_STATUSES = (
('W', 'Ожидание согласия'),
('P', 'На оплате'),
('F', 'Оплачен'),
('C', 'Отклонен'),
('H', 'Сгорел')
)
status = models.CharField(verbose_name='Статус', max_length=1, default='W', choices=BILL_STATUSES) status = models.CharField(verbose_name='Статус', max_length=1, default='W', choices=BILL_STATUSES)
bill_method = models.CharField(verbose_name='Способ оплаты', max_length=2, default='Y', choices=BILL_METHOD)
price = models.CharField(verbose_name='Сумма', max_length=255, null=True, blank=True) price = models.CharField(verbose_name='Сумма', max_length=255, null=True, blank=True)
real_price = models.CharField(verbose_name='Полученная сумма', max_length=255, null=True, blank=True, real_price = models.CharField(verbose_name='Полученная сумма', max_length=255, null=True, blank=True,
help_text='Сумма, минус комиссия') help_text='Сумма, минус комиссия')
service = models.ForeignKey(to=Price, verbose_name='Оплачиваемая услуга') bill_method = models.CharField(verbose_name='Способ оплаты', max_length=2, default='Y', choices=BILL_METHOD)
inside_data = models.TextField(verbose_name='Данные проверки', default='', blank=True, editable=False)
user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='Плательщик', related_name=u'bill_user')
opener = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='Ответственный сотрудник', null=True)
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=u'Комментарий продавца', help_text=u'Будет показано пользователю',
blank=True, editable=False) blank=True, editable=False)
description = models.TextField(verbose_name='Внутренняя заметка', default='') bill = models.ForeignKey(to=Bill, verbose_name="Связный счёт")
def __str__(self): def __str__(self):
return '%s:%s %s' % (self.id, self.get_status_display(), self.user) return '%s:%s %s' % (self.id, self.get_status_display(), self.bill.user)
class Meta: class Meta:
verbose_name = u'Счет' verbose_name = 'Платёж'
verbose_name_plural = u'Счета' verbose_name_plural = 'Платежи'

@ -1,9 +1,5 @@
#! coding: utf-8
from django.contrib import admin from django.contrib import admin
from journals.models import Thread, Journal from journals.models import Thread, Journal
admin.site.register(Thread) admin.site.register(Thread)
admin.site.register(Journal) admin.site.register(Journal)

@ -12,19 +12,6 @@ from lms.global_decorators import transaction_decorator
@transaction_decorator @transaction_decorator
def main_threads(): def main_threads():
print("Инициализация основных тредов")
res = {}
support_list = [
'kate.gazukina@skillbox.ru',
'katerina.ragozina@skillbox.ru',
]
admin_list = [
'andrey.korolev@skillbox.ru',
'pavel.matveev@skillbox.ru',
'anton.kopylov@skillbox.ru',
]
admin_thread, _is_create = Thread.objects.get_or_create( admin_thread, _is_create = Thread.objects.get_or_create(
key='Admin', key='Admin',
@ -32,61 +19,61 @@ def main_threads():
is_staff=True, is_staff=True,
) )
for i in get_user_model().objects.filter(email__in=admin_list): for i in get_user_model().objects.filter(is_superuser=True):
admin_thread.subscribers.add(i) admin_thread.subscribers.add(i)
management_thread, _is_create = Thread.objects.get_or_create( # management_thread, _is_create = Thread.objects.get_or_create(
key='Project_management', # key='Project_management',
text='Тред для проджект-менеджеров, сюда падает статистика разного рода', # text='Тред для проджект-менеджеров, сюда падает статистика разного рода',
is_staff=True, # is_staff=True,
) # )
#
management_thread.parent.add(admin_thread) # management_thread.parent.add(admin_thread)
#
support_thread, _is_create = Thread.objects.get_or_create( # support_thread, _is_create = Thread.objects.get_or_create(
key='Support', # key='Support',
text='Тред сапортов, занимаются поддержкой клиента', # text='Тред сапортов, занимаются поддержкой клиента',
is_staff=True, # is_staff=True,
) # )
#
for i in get_user_model().objects.filter(email__in=support_list): # for i in get_user_model().objects.filter(email__in=support_list):
support_thread.subscribers.add(i) # support_thread.subscribers.add(i)
#
support_thread.parent.add(admin_thread) # support_thread.parent.add(admin_thread)
#
res['library_thread'], _is_create = Thread.objects.get_or_create( # res['library_thread'], _is_create = Thread.objects.get_or_create(
key='Library', # key='Library',
text='Тред <<Библиотека>> сюда прилетает вся инфа по статьям', # text='Тред <<Библиотека>> сюда прилетает вся инфа по статьям',
is_staff=True, # is_staff=True,
) # )
#
res['library_thread'].parent.add(management_thread) # res['library_thread'].parent.add(management_thread)
#
course_thread, _is_create = Thread.objects.get_or_create( # course_thread, _is_create = Thread.objects.get_or_create(
key='Course_thread', # key='Course_thread',
text='Тред курсов', # text='Тред курсов',
is_staff=True, # is_staff=True,
) # )
#
course_thread.parent.add(management_thread) # course_thread.parent.add(management_thread)
#
start_and_end_thread, _is_create = Thread.objects.get_or_create( # start_and_end_thread, _is_create = Thread.objects.get_or_create(
key='Start_and_end', # key='Start_and_end',
text='Тред начала и завершения прохождения какого-либо этапа обучения', # text='Тред начала и завершения прохождения какого-либо этапа обучения',
is_staff=True, # is_staff=True,
) # )
#
start_and_end_thread.parent.add(course_thread) # start_and_end_thread.parent.add(course_thread)
#
res['task_thread'], _is_create = Thread.objects.get_or_create( # res['task_thread'], _is_create = Thread.objects.get_or_create(
key='Tasks', # key='Tasks',
text='Сюда пободают все переписки студентов и преподов', # text='Сюда пободают все переписки студентов и преподов',
is_staff=True, # is_staff=True,
) # )
#
res['task_thread'].parent.add(support_thread) # res['task_thread'].parent.add(support_thread)
#
return res # return res
if __name__ == '__main__': if __name__ == '__main__':

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-10-23 12:08
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('journals', '0002_thread_groups'),
]
operations = [
migrations.AlterField(
model_name='journal',
name='action_type',
field=models.SmallIntegerField(choices=[(0, 'try'), (1, 'yes'), (2, 'no'), (3, 'favorite'), (4, 'watch'), (5, 'start'), (6, 'end'), (7, 'create'), (8, 'update'), (9, 'delete'), (10, 'send_mail')]),
),
migrations.AlterField(
model_name='journal',
name='object_id',
field=models.CharField(max_length=255),
),
migrations.AlterField(
model_name='journal',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Инициатор действия или тот, на ком действие инициируется'),
),
migrations.AlterField(
model_name='thread',
name='groups',
field=models.ManyToManyField(blank=True, to='auth.Group', verbose_name='Группы подписчиков'),
),
]

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-10-23 12:34
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('journals', '0003_auto_20171023_1208'),
]
operations = [
migrations.AlterField(
model_name='journal',
name='object_id',
field=models.PositiveIntegerField(),
),
]

@ -27,8 +27,10 @@ ACTION_CHOICES = (
# Новое API # Новое API
class Journal(models.Model): class Journal(models.Model):
thread = models.ForeignKey(to='Thread', verbose_name=u'Тред') thread = models.ForeignKey(to='Thread', verbose_name='Тред')
user = models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name=u'Инициатор действия') user = models.ForeignKey(
to=settings.AUTH_USER_MODEL, verbose_name='Инициатор действия или тот, на ком действие инициируется'
)
content_type = models.ForeignKey(to=ContentType) content_type = models.ForeignKey(to=ContentType)
extra_data = models.TextField(null=True, blank=True) extra_data = models.TextField(null=True, blank=True)
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
@ -45,8 +47,8 @@ class Thread(models.Model):
text = models.TextField(default='', verbose_name=u'Описание треда') text = models.TextField(default='', verbose_name=u'Описание треда')
is_staff = models.BooleanField(default=False, verbose_name=u'Админская ли табличка') is_staff = models.BooleanField(default=False, verbose_name=u'Админская ли табличка')
recurse_step = models.SmallIntegerField(default=0, verbose_name=u'Поле аптимизации поиска') recurse_step = models.SmallIntegerField(default=0, verbose_name=u'Поле аптимизации поиска')
subscribers = models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name=u'Подписчики', blank=True) subscribers = models.ManyToManyField(to=settings.AUTH_USER_MODEL, verbose_name='Подписчики', blank=True)
groups = models.ManyToManyField(to=Group, verbose_name=u'Подписчики', blank=True) groups = models.ManyToManyField(to=Group, verbose_name='Группы подписчиков', blank=True)
check_subscribe = models.BooleanField(default=True, verbose_name='Проверять ли подписки') check_subscribe = models.BooleanField(default=True, verbose_name='Проверять ли подписки')
parent = models.ManyToManyField(to='self', blank=True, symmetrical=False) parent = models.ManyToManyField(to='self', blank=True, symmetrical=False)
x = models.SmallIntegerField(default=300) x = models.SmallIntegerField(default=300)

@ -0,0 +1 @@
from django.contrib import admin
Loading…
Cancel
Save