666 lines
26 KiB
Python
666 lines
26 KiB
Python
# Generated by Django 4.2.7 on 2025-12-09 21:02
|
||
|
||
from django.conf import settings
|
||
import django.core.validators
|
||
from django.db import migrations, models
|
||
import django.db.models.deletion
|
||
|
||
|
||
class Migration(migrations.Migration):
|
||
initial = True
|
||
|
||
dependencies = [
|
||
("subscriptions", "0001_initial"),
|
||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||
]
|
||
|
||
operations = [
|
||
migrations.CreateModel(
|
||
name="PromoCode",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
(
|
||
"code",
|
||
models.CharField(
|
||
db_index=True, max_length=50, unique=True, verbose_name="Код"
|
||
),
|
||
),
|
||
("name", models.CharField(max_length=200, verbose_name="Название")),
|
||
("description", models.TextField(blank=True, verbose_name="Описание")),
|
||
(
|
||
"discount_type",
|
||
models.CharField(
|
||
choices=[
|
||
("percent", "Процент"),
|
||
("fixed", "Фиксированная сумма"),
|
||
],
|
||
default="percent",
|
||
max_length=10,
|
||
verbose_name="Тип скидки",
|
||
),
|
||
),
|
||
(
|
||
"discount_value",
|
||
models.DecimalField(
|
||
decimal_places=2,
|
||
help_text="Процент (0-100) или фиксированная сумма",
|
||
max_digits=10,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Размер скидки",
|
||
),
|
||
),
|
||
(
|
||
"max_uses",
|
||
models.IntegerField(
|
||
blank=True,
|
||
help_text="Оставьте пустым для неограниченного",
|
||
null=True,
|
||
validators=[django.core.validators.MinValueValidator(1)],
|
||
verbose_name="Максимум использований",
|
||
),
|
||
),
|
||
(
|
||
"current_uses",
|
||
models.IntegerField(
|
||
default=0,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Текущих использований",
|
||
),
|
||
),
|
||
(
|
||
"valid_until",
|
||
models.DateTimeField(
|
||
blank=True, null=True, verbose_name="Действителен до"
|
||
),
|
||
),
|
||
(
|
||
"is_active",
|
||
models.BooleanField(default=True, verbose_name="Активен"),
|
||
),
|
||
(
|
||
"created_at",
|
||
models.DateTimeField(auto_now_add=True, verbose_name="Создан"),
|
||
),
|
||
(
|
||
"updated_at",
|
||
models.DateTimeField(auto_now=True, verbose_name="Обновлен"),
|
||
),
|
||
(
|
||
"applicable_plans",
|
||
models.ManyToManyField(
|
||
blank=True,
|
||
help_text="Если не указано - применим ко всем планам",
|
||
to="subscriptions.subscriptionplan",
|
||
verbose_name="Применим к планам",
|
||
),
|
||
),
|
||
(
|
||
"created_by",
|
||
models.ForeignKey(
|
||
blank=True,
|
||
null=True,
|
||
on_delete=django.db.models.deletion.SET_NULL,
|
||
related_name="created_promocodes",
|
||
to=settings.AUTH_USER_MODEL,
|
||
verbose_name="Создал",
|
||
),
|
||
),
|
||
],
|
||
options={
|
||
"verbose_name": "Промокод",
|
||
"verbose_name_plural": "Промокоды",
|
||
"ordering": ["-created_at"],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name="ReferralLevel",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
("level", models.IntegerField(unique=True, verbose_name="Уровень")),
|
||
("name", models.CharField(max_length=100, verbose_name="Название")),
|
||
(
|
||
"points_required",
|
||
models.IntegerField(
|
||
help_text="Минимальное количество очков для достижения уровня",
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Требуется очков",
|
||
),
|
||
),
|
||
(
|
||
"bonus_payment_percent",
|
||
models.IntegerField(
|
||
help_text="Максимальный процент подписки, который можно оплатить бонусами",
|
||
validators=[
|
||
django.core.validators.MinValueValidator(0),
|
||
django.core.validators.MaxValueValidator(100),
|
||
],
|
||
verbose_name="% оплаты бонусами",
|
||
),
|
||
),
|
||
(
|
||
"icon",
|
||
models.CharField(blank=True, max_length=50, verbose_name="Иконка"),
|
||
),
|
||
],
|
||
options={
|
||
"verbose_name": "Уровень реферальной программы",
|
||
"verbose_name_plural": "Уровни реферальной программы",
|
||
"ordering": ["level"],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name="ReferralSettings",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
(
|
||
"level1_commission",
|
||
models.DecimalField(
|
||
decimal_places=2,
|
||
default=10.0,
|
||
help_text="Процент от оплаты прямого реферала",
|
||
max_digits=5,
|
||
validators=[
|
||
django.core.validators.MinValueValidator(0),
|
||
django.core.validators.MaxValueValidator(100),
|
||
],
|
||
verbose_name="Комиссия 1 уровня (%)",
|
||
),
|
||
),
|
||
(
|
||
"level2_commission",
|
||
models.DecimalField(
|
||
decimal_places=2,
|
||
default=5.0,
|
||
help_text="Процент от оплаты реферала реферала",
|
||
max_digits=5,
|
||
validators=[
|
||
django.core.validators.MinValueValidator(0),
|
||
django.core.validators.MaxValueValidator(100),
|
||
],
|
||
verbose_name="Комиссия 2 уровня (%)",
|
||
),
|
||
),
|
||
(
|
||
"points_direct_referral",
|
||
models.IntegerField(
|
||
default=5,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Очков за прямого реферала",
|
||
),
|
||
),
|
||
(
|
||
"points_indirect_referral",
|
||
models.IntegerField(
|
||
default=2,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Очков за реферала реферала",
|
||
),
|
||
),
|
||
(
|
||
"updated_at",
|
||
models.DateTimeField(auto_now=True, verbose_name="Обновлено"),
|
||
),
|
||
],
|
||
options={
|
||
"verbose_name": "Настройки реферальной программы",
|
||
"verbose_name_plural": "Настройки реферальной программы",
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name="UserReferralProfile",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
(
|
||
"referral_code",
|
||
models.CharField(
|
||
db_index=True,
|
||
max_length=20,
|
||
unique=True,
|
||
verbose_name="Реферальный код",
|
||
),
|
||
),
|
||
(
|
||
"total_points",
|
||
models.IntegerField(
|
||
default=0,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Всего очков",
|
||
),
|
||
),
|
||
(
|
||
"direct_referrals_count",
|
||
models.IntegerField(
|
||
default=0,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Прямых рефералов",
|
||
),
|
||
),
|
||
(
|
||
"indirect_referrals_count",
|
||
models.IntegerField(
|
||
default=0,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Непрямых рефералов",
|
||
),
|
||
),
|
||
(
|
||
"total_earned",
|
||
models.DecimalField(
|
||
decimal_places=2,
|
||
default=0,
|
||
max_digits=10,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Всего заработано (₽)",
|
||
),
|
||
),
|
||
(
|
||
"created_at",
|
||
models.DateTimeField(auto_now_add=True, verbose_name="Создан"),
|
||
),
|
||
(
|
||
"updated_at",
|
||
models.DateTimeField(auto_now=True, verbose_name="Обновлен"),
|
||
),
|
||
(
|
||
"current_level",
|
||
models.ForeignKey(
|
||
blank=True,
|
||
null=True,
|
||
on_delete=django.db.models.deletion.SET_NULL,
|
||
to="referrals.referrallevel",
|
||
verbose_name="Текущий уровень",
|
||
),
|
||
),
|
||
(
|
||
"referred_by",
|
||
models.ForeignKey(
|
||
blank=True,
|
||
null=True,
|
||
on_delete=django.db.models.deletion.SET_NULL,
|
||
related_name="referrals",
|
||
to=settings.AUTH_USER_MODEL,
|
||
verbose_name="Пригласил",
|
||
),
|
||
),
|
||
(
|
||
"user",
|
||
models.OneToOneField(
|
||
on_delete=django.db.models.deletion.CASCADE,
|
||
related_name="referral_profile",
|
||
to=settings.AUTH_USER_MODEL,
|
||
verbose_name="Пользователь",
|
||
),
|
||
),
|
||
],
|
||
options={
|
||
"verbose_name": "Реферальный профиль",
|
||
"verbose_name_plural": "Реферальные профили",
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name="ReferralEarning",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
(
|
||
"level",
|
||
models.IntegerField(
|
||
help_text="1 - прямой реферал, 2 - реферал реферала",
|
||
validators=[
|
||
django.core.validators.MinValueValidator(1),
|
||
django.core.validators.MaxValueValidator(2),
|
||
],
|
||
verbose_name="Уровень",
|
||
),
|
||
),
|
||
(
|
||
"payment_amount",
|
||
models.DecimalField(
|
||
decimal_places=2,
|
||
max_digits=10,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Сумма платежа (₽)",
|
||
),
|
||
),
|
||
(
|
||
"commission_percent",
|
||
models.DecimalField(
|
||
decimal_places=2,
|
||
max_digits=5,
|
||
validators=[
|
||
django.core.validators.MinValueValidator(0),
|
||
django.core.validators.MaxValueValidator(100),
|
||
],
|
||
verbose_name="Процент комиссии",
|
||
),
|
||
),
|
||
(
|
||
"earned_amount",
|
||
models.DecimalField(
|
||
decimal_places=2,
|
||
max_digits=10,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Заработано (₽)",
|
||
),
|
||
),
|
||
(
|
||
"created_at",
|
||
models.DateTimeField(auto_now_add=True, verbose_name="Создан"),
|
||
),
|
||
(
|
||
"payment",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.CASCADE,
|
||
to="subscriptions.payment",
|
||
verbose_name="Платеж",
|
||
),
|
||
),
|
||
(
|
||
"referral",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.CASCADE,
|
||
related_name="generated_earnings",
|
||
to=settings.AUTH_USER_MODEL,
|
||
verbose_name="Реферал",
|
||
),
|
||
),
|
||
(
|
||
"referrer",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.CASCADE,
|
||
related_name="referral_earnings",
|
||
to=settings.AUTH_USER_MODEL,
|
||
verbose_name="Реферер",
|
||
),
|
||
),
|
||
],
|
||
options={
|
||
"verbose_name": "Заработок с реферала",
|
||
"verbose_name_plural": "Заработки с рефералов",
|
||
"ordering": ["-created_at"],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name="PromoCodeUsage",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
(
|
||
"original_amount",
|
||
models.DecimalField(
|
||
decimal_places=2,
|
||
max_digits=10,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Исходная сумма (₽)",
|
||
),
|
||
),
|
||
(
|
||
"discount_amount",
|
||
models.DecimalField(
|
||
decimal_places=2,
|
||
max_digits=10,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Размер скидки (₽)",
|
||
),
|
||
),
|
||
(
|
||
"final_amount",
|
||
models.DecimalField(
|
||
decimal_places=2,
|
||
max_digits=10,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Итоговая сумма (₽)",
|
||
),
|
||
),
|
||
(
|
||
"created_at",
|
||
models.DateTimeField(auto_now_add=True, verbose_name="Использован"),
|
||
),
|
||
(
|
||
"payment",
|
||
models.ForeignKey(
|
||
blank=True,
|
||
null=True,
|
||
on_delete=django.db.models.deletion.CASCADE,
|
||
to="subscriptions.payment",
|
||
verbose_name="Платеж",
|
||
),
|
||
),
|
||
(
|
||
"promo_code",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.CASCADE,
|
||
related_name="usages",
|
||
to="referrals.promocode",
|
||
verbose_name="Промокод",
|
||
),
|
||
),
|
||
(
|
||
"user",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.CASCADE,
|
||
related_name="promocode_usages",
|
||
to=settings.AUTH_USER_MODEL,
|
||
verbose_name="Пользователь",
|
||
),
|
||
),
|
||
],
|
||
options={
|
||
"verbose_name": "Использование промокода",
|
||
"verbose_name_plural": "Использования промокодов",
|
||
"ordering": ["-created_at"],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name="PointsTransaction",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
("points", models.IntegerField(verbose_name="Очки")),
|
||
("reason", models.CharField(max_length=255, verbose_name="Причина")),
|
||
(
|
||
"balance_after",
|
||
models.IntegerField(
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Баланс после",
|
||
),
|
||
),
|
||
(
|
||
"created_at",
|
||
models.DateTimeField(auto_now_add=True, verbose_name="Создан"),
|
||
),
|
||
(
|
||
"user",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.CASCADE,
|
||
related_name="points_transactions",
|
||
to=settings.AUTH_USER_MODEL,
|
||
verbose_name="Пользователь",
|
||
),
|
||
),
|
||
],
|
||
options={
|
||
"verbose_name": "Транзакция очков",
|
||
"verbose_name_plural": "Транзакции очков",
|
||
"ordering": ["-created_at"],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name="BonusTransaction",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
(
|
||
"amount",
|
||
models.DecimalField(
|
||
decimal_places=2,
|
||
max_digits=10,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Сумма (₽)",
|
||
),
|
||
),
|
||
(
|
||
"transaction_type",
|
||
models.CharField(
|
||
choices=[("earn", "Начисление"), ("spend", "Списание")],
|
||
max_length=10,
|
||
verbose_name="Тип транзакции",
|
||
),
|
||
),
|
||
("reason", models.CharField(max_length=255, verbose_name="Причина")),
|
||
(
|
||
"balance_after",
|
||
models.DecimalField(
|
||
decimal_places=2,
|
||
max_digits=10,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Баланс после (₽)",
|
||
),
|
||
),
|
||
(
|
||
"created_at",
|
||
models.DateTimeField(auto_now_add=True, verbose_name="Создан"),
|
||
),
|
||
(
|
||
"user",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.CASCADE,
|
||
related_name="bonus_transactions",
|
||
to=settings.AUTH_USER_MODEL,
|
||
verbose_name="Пользователь",
|
||
),
|
||
),
|
||
],
|
||
options={
|
||
"verbose_name": "Транзакция бонусов",
|
||
"verbose_name_plural": "Транзакции бонусов",
|
||
"ordering": ["-created_at"],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name="BonusAccount",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
(
|
||
"balance",
|
||
models.DecimalField(
|
||
decimal_places=2,
|
||
default=0,
|
||
max_digits=10,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Баланс (₽)",
|
||
),
|
||
),
|
||
(
|
||
"total_earned",
|
||
models.DecimalField(
|
||
decimal_places=2,
|
||
default=0,
|
||
max_digits=10,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Всего заработано (₽)",
|
||
),
|
||
),
|
||
(
|
||
"total_spent",
|
||
models.DecimalField(
|
||
decimal_places=2,
|
||
default=0,
|
||
max_digits=10,
|
||
validators=[django.core.validators.MinValueValidator(0)],
|
||
verbose_name="Всего потрачено (₽)",
|
||
),
|
||
),
|
||
(
|
||
"created_at",
|
||
models.DateTimeField(auto_now_add=True, verbose_name="Создан"),
|
||
),
|
||
(
|
||
"updated_at",
|
||
models.DateTimeField(auto_now=True, verbose_name="Обновлен"),
|
||
),
|
||
(
|
||
"user",
|
||
models.OneToOneField(
|
||
on_delete=django.db.models.deletion.CASCADE,
|
||
related_name="bonus_account",
|
||
to=settings.AUTH_USER_MODEL,
|
||
verbose_name="Пользователь",
|
||
),
|
||
),
|
||
],
|
||
options={
|
||
"verbose_name": "Бонусный счет",
|
||
"verbose_name_plural": "Бонусные счета",
|
||
},
|
||
),
|
||
]
|