291 lines
19 KiB
Python
291 lines
19 KiB
Python
# Generated by Django 5.2.7 on 2025-10-25 13:44
|
||
|
||
import django.db.models.deletion
|
||
from django.conf import settings
|
||
from django.db import migrations, models
|
||
|
||
|
||
class Migration(migrations.Migration):
|
||
|
||
initial = True
|
||
|
||
dependencies = [
|
||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||
]
|
||
|
||
operations = [
|
||
migrations.CreateModel(
|
||
name='ProductVariantGroup',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('name', models.CharField(max_length=200, verbose_name='Название')),
|
||
('description', models.TextField(blank=True, verbose_name='Описание')),
|
||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')),
|
||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Дата обновления')),
|
||
],
|
||
options={
|
||
'verbose_name': 'Группа вариантов',
|
||
'verbose_name_plural': 'Группы вариантов',
|
||
'ordering': ['name'],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='SKUCounter',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('counter_type', models.CharField(choices=[('product', 'Product Counter'), ('kit', 'Kit Counter'), ('category', 'Category Counter')], max_length=20, unique=True, verbose_name='Тип счетчика')),
|
||
('current_value', models.IntegerField(default=0, verbose_name='Текущее значение')),
|
||
],
|
||
options={
|
||
'verbose_name': 'Счетчик артикулов',
|
||
'verbose_name_plural': 'Счетчики артикулов',
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='ProductCategory',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('name', models.CharField(max_length=200, verbose_name='Название')),
|
||
('sku', models.CharField(blank=True, db_index=True, max_length=100, null=True, unique=True, verbose_name='Артикул')),
|
||
('slug', models.SlugField(blank=True, max_length=200, unique=True, verbose_name='URL-идентификатор')),
|
||
('is_active', models.BooleanField(default=True, verbose_name='Активна')),
|
||
('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Дата создания')),
|
||
('updated_at', models.DateTimeField(auto_now=True, null=True, verbose_name='Дата обновления')),
|
||
('is_deleted', models.BooleanField(db_index=True, default=False, verbose_name='Удалена')),
|
||
('deleted_at', models.DateTimeField(blank=True, null=True, verbose_name='Время удаления')),
|
||
('deleted_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='deleted_categories', to=settings.AUTH_USER_MODEL, verbose_name='Удалена пользователем')),
|
||
('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='children', to='products.productcategory', verbose_name='Родительская категория')),
|
||
],
|
||
options={
|
||
'verbose_name': 'Категория товара',
|
||
'verbose_name_plural': 'Категории товаров',
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='Product',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('name', models.CharField(max_length=200, verbose_name='Название')),
|
||
('sku', models.CharField(blank=True, db_index=True, max_length=100, null=True, verbose_name='Артикул')),
|
||
('slug', models.SlugField(blank=True, max_length=200, unique=True, verbose_name='URL-идентификатор')),
|
||
('variant_suffix', models.CharField(blank=True, help_text='Суффикс для артикула (например: 50, 60, S, M). Автоматически извлекается из названия.', max_length=20, null=True, verbose_name='Суффикс варианта')),
|
||
('description', models.TextField(blank=True, null=True, verbose_name='Описание')),
|
||
('unit', models.CharField(choices=[('шт', 'Штука'), ('м', 'Метр'), ('г', 'Грамм'), ('л', 'Литр'), ('кг', 'Килограмм')], default='шт', max_length=10, verbose_name='Единица измерения')),
|
||
('cost_price', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Себестоимость')),
|
||
('sale_price', models.DecimalField(decimal_places=2, max_digits=10, 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='Дата обновления')),
|
||
('search_keywords', models.TextField(blank=True, help_text='Автоматически генерируется из названия, артикула, описания и категории. Можно дополнить вручную.', verbose_name='Ключевые слова для поиска')),
|
||
('is_deleted', models.BooleanField(db_index=True, default=False, verbose_name='Удален')),
|
||
('deleted_at', models.DateTimeField(blank=True, null=True, verbose_name='Время удаления')),
|
||
('deleted_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='deleted_products', to=settings.AUTH_USER_MODEL, verbose_name='Удален пользователем')),
|
||
('categories', models.ManyToManyField(blank=True, related_name='products', to='products.productcategory', verbose_name='Категории')),
|
||
],
|
||
options={
|
||
'verbose_name': 'Товар',
|
||
'verbose_name_plural': 'Товары',
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='ProductCategoryPhoto',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('image', models.ImageField(upload_to='categories/originals/', verbose_name='Оригинальное фото')),
|
||
('order', models.PositiveIntegerField(default=0, verbose_name='Порядок')),
|
||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')),
|
||
('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='photos', to='products.productcategory', verbose_name='Категория')),
|
||
],
|
||
options={
|
||
'verbose_name': 'Фото категории',
|
||
'verbose_name_plural': 'Фото категорий',
|
||
'ordering': ['order', '-created_at'],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='ProductKit',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('name', models.CharField(max_length=200, verbose_name='Название')),
|
||
('sku', models.CharField(blank=True, max_length=100, null=True, verbose_name='Артикул')),
|
||
('slug', models.SlugField(max_length=200, unique=True, verbose_name='URL-идентификатор')),
|
||
('description', models.TextField(blank=True, null=True, verbose_name='Описание')),
|
||
('is_active', models.BooleanField(default=True, verbose_name='Активен')),
|
||
('pricing_method', models.CharField(choices=[('fixed', 'Фиксированная цена'), ('from_sale_prices', 'По ценам продажи компонентов'), ('from_cost_plus_percent', 'Себестоимость + процент наценки'), ('from_cost_plus_amount', 'Себестоимость + фикс. наценка')], default='from_sale_prices', max_length=30, verbose_name='Метод ценообразования')),
|
||
('fixed_price', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='Фиксированная цена')),
|
||
('markup_percent', models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True, verbose_name='Процент наценки')),
|
||
('markup_amount', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='Фиксированная наценка')),
|
||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')),
|
||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Дата обновления')),
|
||
('is_deleted', models.BooleanField(db_index=True, default=False, verbose_name='Удален')),
|
||
('deleted_at', models.DateTimeField(blank=True, null=True, verbose_name='Время удаления')),
|
||
('categories', models.ManyToManyField(blank=True, related_name='kits', to='products.productcategory', verbose_name='Категории')),
|
||
('deleted_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='deleted_kits', to=settings.AUTH_USER_MODEL, verbose_name='Удален пользователем')),
|
||
],
|
||
options={
|
||
'verbose_name': 'Комплект',
|
||
'verbose_name_plural': 'Комплекты',
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='ProductKitPhoto',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('image', models.ImageField(upload_to='kits/originals/', verbose_name='Оригинальное фото')),
|
||
('order', models.PositiveIntegerField(default=0, verbose_name='Порядок')),
|
||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')),
|
||
('kit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='photos', to='products.productkit', verbose_name='Комплект')),
|
||
],
|
||
options={
|
||
'verbose_name': 'Фото комплекта',
|
||
'verbose_name_plural': 'Фото комплектов',
|
||
'ordering': ['order', '-created_at'],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='ProductPhoto',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('image', models.ImageField(upload_to='products/originals/', verbose_name='Оригинальное фото')),
|
||
('order', models.PositiveIntegerField(default=0, verbose_name='Порядок')),
|
||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')),
|
||
('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='photos', to='products.product', verbose_name='Товар')),
|
||
],
|
||
options={
|
||
'verbose_name': 'Фото товара',
|
||
'verbose_name_plural': 'Фото товаров',
|
||
'ordering': ['order', '-created_at'],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='ProductTag',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('name', models.CharField(max_length=100, unique=True, verbose_name='Название')),
|
||
('slug', models.SlugField(max_length=100, unique=True, verbose_name='URL-идентификатор')),
|
||
('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Дата создания')),
|
||
('updated_at', models.DateTimeField(auto_now=True, null=True, verbose_name='Дата обновления')),
|
||
('is_deleted', models.BooleanField(db_index=True, default=False, verbose_name='Удален')),
|
||
('deleted_at', models.DateTimeField(blank=True, null=True, verbose_name='Время удаления')),
|
||
('deleted_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='deleted_tags', to=settings.AUTH_USER_MODEL, verbose_name='Удален пользователем')),
|
||
],
|
||
options={
|
||
'verbose_name': 'Тег товара',
|
||
'verbose_name_plural': 'Теги товаров',
|
||
},
|
||
),
|
||
migrations.AddField(
|
||
model_name='productkit',
|
||
name='tags',
|
||
field=models.ManyToManyField(blank=True, related_name='kits', to='products.producttag', verbose_name='Теги'),
|
||
),
|
||
migrations.AddField(
|
||
model_name='product',
|
||
name='tags',
|
||
field=models.ManyToManyField(blank=True, related_name='products', to='products.producttag', verbose_name='Теги'),
|
||
),
|
||
migrations.AddField(
|
||
model_name='product',
|
||
name='variant_groups',
|
||
field=models.ManyToManyField(blank=True, related_name='products', to='products.productvariantgroup', verbose_name='Группы вариантов'),
|
||
),
|
||
migrations.CreateModel(
|
||
name='KitItem',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('quantity', models.DecimalField(blank=True, decimal_places=3, max_digits=10, null=True, verbose_name='Количество')),
|
||
('notes', models.CharField(blank=True, max_length=200, verbose_name='Примечание')),
|
||
('product', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='kit_items_direct', to='products.product', verbose_name='Конкретный товар')),
|
||
('kit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='kit_items', to='products.productkit', verbose_name='Комплект')),
|
||
('variant_group', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='kit_items', to='products.productvariantgroup', verbose_name='Группа вариантов')),
|
||
],
|
||
options={
|
||
'verbose_name': 'Компонент комплекта',
|
||
'verbose_name_plural': 'Компоненты комплектов',
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='KitItemPriority',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('priority', models.PositiveIntegerField(default=0, help_text='Меньше = выше приоритет (0 - наивысший)')),
|
||
('kit_item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='priorities', to='products.kititem', verbose_name='Позиция в букете')),
|
||
('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='products.product', verbose_name='Товар')),
|
||
],
|
||
options={
|
||
'verbose_name': 'Приоритет варианта',
|
||
'verbose_name_plural': 'Приоритеты вариантов',
|
||
'ordering': ['priority', 'id'],
|
||
'unique_together': {('kit_item', 'product')},
|
||
},
|
||
),
|
||
migrations.AddIndex(
|
||
model_name='productcategory',
|
||
index=models.Index(fields=['is_active'], name='products_pr_is_acti_226e74_idx'),
|
||
),
|
||
migrations.AddIndex(
|
||
model_name='productcategory',
|
||
index=models.Index(fields=['is_deleted'], name='products_pr_is_dele_2a96d1_idx'),
|
||
),
|
||
migrations.AddIndex(
|
||
model_name='productcategory',
|
||
index=models.Index(fields=['is_deleted', 'created_at'], name='products_pr_is_dele_b8cdf3_idx'),
|
||
),
|
||
migrations.AddIndex(
|
||
model_name='producttag',
|
||
index=models.Index(fields=['is_deleted'], name='products_pr_is_dele_ea9be0_idx'),
|
||
),
|
||
migrations.AddIndex(
|
||
model_name='producttag',
|
||
index=models.Index(fields=['is_deleted', 'created_at'], name='products_pr_is_dele_bc2d9c_idx'),
|
||
),
|
||
migrations.AddIndex(
|
||
model_name='productkit',
|
||
index=models.Index(fields=['is_active'], name='products_pr_is_acti_214d4f_idx'),
|
||
),
|
||
migrations.AddIndex(
|
||
model_name='productkit',
|
||
index=models.Index(fields=['slug'], name='products_pr_slug_b5e185_idx'),
|
||
),
|
||
migrations.AddIndex(
|
||
model_name='productkit',
|
||
index=models.Index(fields=['is_deleted'], name='products_pr_is_dele_e83a83_idx'),
|
||
),
|
||
migrations.AddIndex(
|
||
model_name='productkit',
|
||
index=models.Index(fields=['is_deleted', 'created_at'], name='products_pr_is_dele_1e5bec_idx'),
|
||
),
|
||
migrations.AddIndex(
|
||
model_name='product',
|
||
index=models.Index(fields=['is_active'], name='products_pr_is_acti_ca4d9a_idx'),
|
||
),
|
||
migrations.AddIndex(
|
||
model_name='product',
|
||
index=models.Index(fields=['is_deleted'], name='products_pr_is_dele_3bba04_idx'),
|
||
),
|
||
migrations.AddIndex(
|
||
model_name='product',
|
||
index=models.Index(fields=['is_deleted', 'created_at'], name='products_pr_is_dele_f30efb_idx'),
|
||
),
|
||
migrations.AddIndex(
|
||
model_name='kititem',
|
||
index=models.Index(fields=['kit'], name='products_ki_kit_id_d28dc9_idx'),
|
||
),
|
||
migrations.AddIndex(
|
||
model_name='kititem',
|
||
index=models.Index(fields=['product'], name='products_ki_product_d2ad00_idx'),
|
||
),
|
||
migrations.AddIndex(
|
||
model_name='kititem',
|
||
index=models.Index(fields=['variant_group'], name='products_ki_variant_e42628_idx'),
|
||
),
|
||
migrations.AddIndex(
|
||
model_name='kititem',
|
||
index=models.Index(fields=['kit', 'product'], name='products_ki_kit_id_14738f_idx'),
|
||
),
|
||
migrations.AddIndex(
|
||
model_name='kititem',
|
||
index=models.Index(fields=['kit', 'variant_group'], name='products_ki_kit_id_8199a8_idx'),
|
||
),
|
||
]
|