# Generated by Django 5.0.10 on 2025-12-29 22:19 import django.db.models.deletion import phonenumber_field.modelfields 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='DocumentCounter', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('counter_type', models.CharField(choices=[('transfer', 'Перемещение товара'), ('writeoff', 'Списание товара'), ('incoming', 'Поступление товара'), ('inventory', 'Инвентаризация'), ('transformation', 'Трансформация товара')], max_length=20, unique=True, verbose_name='Тип счетчика')), ('current_value', models.IntegerField(default=0, verbose_name='Текущее значение')), ], options={ 'verbose_name': 'Счетчик документов', 'verbose_name_plural': 'Счетчики документов', }, ), migrations.CreateModel( name='Inventory', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('document_number', models.CharField(blank=True, db_index=True, max_length=100, null=True, unique=True, verbose_name='Номер документа')), ('date', models.DateTimeField(auto_now_add=True, verbose_name='Дата инвентаризации')), ('status', models.CharField(choices=[('draft', 'Черновик'), ('processing', 'В обработке'), ('completed', 'Завершена')], default='draft', max_length=20, verbose_name='Статус')), ('notes', models.TextField(blank=True, null=True, verbose_name='Примечания')), ], options={ 'verbose_name': 'Инвентаризация', 'verbose_name_plural': 'Инвентаризации', 'ordering': ['-date'], }, ), migrations.CreateModel( name='InventoryLine', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity_system', models.DecimalField(decimal_places=3, max_digits=10, verbose_name='Количество в системе')), ('quantity_fact', models.DecimalField(decimal_places=3, help_text='Количество свободных товаров, подсчитанных физически', max_digits=10, verbose_name='Подсчитано (факт, свободные)')), ('difference', models.DecimalField(decimal_places=3, default=0, editable=False, help_text='(Подсчитано + Зарезервировано) - Всего на складе', max_digits=10, verbose_name='Итоговая разница')), ('processed', models.BooleanField(default=False, verbose_name='Обработана (создана операция)')), ('snapshot_quantity_available', models.DecimalField(blank=True, decimal_places=3, help_text='Всего на складе на момент завершения инвентаризации', max_digits=10, null=True, verbose_name='Всего на складе (snapshot)')), ('snapshot_quantity_reserved', models.DecimalField(blank=True, decimal_places=3, help_text='В резервах на момент завершения инвентаризации', max_digits=10, null=True, verbose_name='В резервах (snapshot)')), ('snapshot_quantity_system', models.DecimalField(blank=True, decimal_places=3, help_text='В системе свободно на момент завершения инвентаризации', max_digits=10, null=True, verbose_name='В системе свободно (snapshot)')), ('snapshot_difference', models.DecimalField(blank=True, decimal_places=3, help_text='Итоговая разница на момент завершения инвентаризации', max_digits=10, null=True, verbose_name='Итоговая разница (snapshot)')), ], options={ 'verbose_name': 'Строка инвентаризации', 'verbose_name_plural': 'Строки инвентаризации', }, ), migrations.CreateModel( name='Reservation', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.DecimalField(decimal_places=3, max_digits=10, verbose_name='Количество')), ('status', models.CharField(choices=[('reserved', 'Зарезервирован'), ('released', 'Освобожден'), ('converted_to_sale', 'Преобразован в продажу'), ('converted_to_writeoff', 'Преобразован в списание'), ('converted_to_transformation', 'Преобразован в трансформацию')], default='reserved', max_length=30, verbose_name='Статус')), ('reserved_at', models.DateTimeField(auto_now_add=True, verbose_name='Дата резервирования')), ('released_at', models.DateTimeField(blank=True, null=True, verbose_name='Дата освобождения')), ('converted_at', models.DateTimeField(blank=True, help_text='Дата преобразования в продажу или списание', null=True, verbose_name='Дата преобразования')), ('cart_lock_expires_at', models.DateTimeField(blank=True, help_text='Время истечения блокировки в корзине (для витринных комплектов)', null=True, verbose_name='Блокировка корзины истекает')), ('cart_session_id', models.CharField(blank=True, help_text='Дополнительная идентификация сессии для надежности', max_length=100, null=True, verbose_name='ID сессии корзины')), ], options={ 'verbose_name': 'Резервирование', 'verbose_name_plural': 'Резервирования', 'ordering': ['-reserved_at'], }, ), migrations.CreateModel( name='Sale', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.DecimalField(decimal_places=3, max_digits=10, verbose_name='Количество')), ('sale_price', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Цена продажи')), ('document_number', models.CharField(blank=True, max_length=100, null=True, verbose_name='Номер документа')), ('date', models.DateTimeField(auto_now_add=True, verbose_name='Дата операции')), ('processed', models.BooleanField(default=False, verbose_name='Обработана (FIFO применена)')), ], options={ 'verbose_name': 'Продажа', 'verbose_name_plural': 'Продажи', 'ordering': ['-date'], }, ), migrations.CreateModel( name='SaleBatchAllocation', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.DecimalField(decimal_places=3, max_digits=10, verbose_name='Количество')), ('cost_price', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Закупочная цена')), ], options={ 'verbose_name': 'Распределение продажи по партиям', 'verbose_name_plural': 'Распределения продаж по партиям', }, ), migrations.CreateModel( name='Showcase', 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, null=True, verbose_name='Описание')), ('is_active', models.BooleanField(default=True, verbose_name='Активна')), ('is_default', models.BooleanField(default=False, 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': ['warehouse', 'name'], }, ), migrations.CreateModel( name='ShowcaseItem', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('status', models.CharField(choices=[('available', 'Доступен'), ('in_cart', 'В корзине'), ('sold', 'Продан'), ('dismantled', 'Разобран')], db_index=True, default='available', max_length=20, verbose_name='Статус')), ('sold_at', models.DateTimeField(blank=True, null=True, verbose_name='Дата продажи')), ('cart_lock_expires_at', models.DateTimeField(blank=True, null=True, verbose_name='Блокировка истекает')), ('cart_session_id', models.CharField(blank=True, max_length=100, null=True, verbose_name='ID сессии корзины')), ('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': 'Экземпляры на витрине', }, ), migrations.CreateModel( name='Stock', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity_available', models.DecimalField(decimal_places=3, default=0, editable=False, max_digits=10, verbose_name='Доступное количество')), ('quantity_reserved', models.DecimalField(decimal_places=3, default=0, editable=False, max_digits=10, verbose_name='Зарезервированное количество')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Дата обновления')), ], options={ 'verbose_name': 'Остаток на складе', 'verbose_name_plural': 'Остатки на складе', }, ), migrations.CreateModel( name='StockBatch', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.DecimalField(decimal_places=3, max_digits=10, verbose_name='Количество')), ('cost_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='Дата обновления')), ], options={ 'verbose_name': 'Партия товара', 'verbose_name_plural': 'Партии товаров', 'ordering': ['created_at'], }, ), migrations.CreateModel( name='TransferDocument', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('document_number', models.CharField(db_index=True, max_length=100, unique=True, verbose_name='Номер документа')), ('notes', models.TextField(blank=True, null=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': ['-created_at'], }, ), migrations.CreateModel( name='TransferDocumentItem', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.DecimalField(decimal_places=3, max_digits=10, verbose_name='Количество')), ], options={ 'verbose_name': 'Строка перемещения', 'verbose_name_plural': 'Строки перемещения', 'ordering': ['id'], }, ), migrations.CreateModel( name='Transformation', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('document_number', models.CharField(db_index=True, max_length=100, unique=True, verbose_name='Номер документа')), ('status', models.CharField(choices=[('draft', 'Черновик'), ('completed', 'Проведён'), ('cancelled', 'Отменён')], db_index=True, default='draft', max_length=20, verbose_name='Статус')), ('date', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')), ('comment', 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': ['-date'], }, ), migrations.CreateModel( name='TransformationInput', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.DecimalField(decimal_places=3, max_digits=10, verbose_name='Количество')), ], options={ 'verbose_name': 'Входной товар трансформации', 'verbose_name_plural': 'Входные товары трансформации', }, ), migrations.CreateModel( name='TransformationOutput', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.DecimalField(decimal_places=3, max_digits=10, verbose_name='Количество')), ], options={ 'verbose_name': 'Выходной товар трансформации', 'verbose_name_plural': 'Выходные товары трансформации', }, ), migrations.CreateModel( name='Warehouse', 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, null=True, verbose_name='Описание')), ('street', models.CharField(blank=True, max_length=255, null=True, verbose_name='Улица')), ('building_number', models.CharField(blank=True, max_length=20, null=True, verbose_name='Номер здания')), ('phone', phonenumber_field.modelfields.PhoneNumberField(blank=True, max_length=128, null=True, region='BY', verbose_name='Телефон')), ('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='Email')), ('is_active', models.BooleanField(default=True, verbose_name='Активен')), ('is_default', models.BooleanField(default=False, help_text='Автоматически выбирается при создании новых документов', verbose_name='Склад по умолчанию')), ('is_pickup_point', models.BooleanField(default=True, help_text='Можно ли выбрать этот склад как точку самовывоза заказа', 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': 'Склады', }, ), migrations.CreateModel( name='WriteOff', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.DecimalField(decimal_places=3, max_digits=10, verbose_name='Количество')), ('reason', models.CharField(choices=[('damage', 'Повреждение'), ('spoilage', 'Порча'), ('shortage', 'Недостача'), ('inventory', 'Инвентаризационная недостача'), ('other', 'Другое')], default='other', max_length=20, verbose_name='Причина')), ('cost_price', models.DecimalField(decimal_places=2, editable=False, max_digits=10, verbose_name='Закупочная цена')), ('document_number', models.CharField(blank=True, max_length=100, null=True, verbose_name='Номер документа')), ('notes', models.TextField(blank=True, null=True, verbose_name='Примечания')), ('date', models.DateTimeField(auto_now_add=True, verbose_name='Дата операции')), ], options={ 'verbose_name': 'Списание', 'verbose_name_plural': 'Списания', 'ordering': ['-date'], }, ), migrations.CreateModel( name='WriteOffDocument', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('document_number', models.CharField(db_index=True, max_length=100, unique=True, verbose_name='Номер документа')), ('status', models.CharField(choices=[('draft', 'Черновик'), ('confirmed', 'Проведён'), ('cancelled', 'Отменён')], db_index=True, default='draft', max_length=20, verbose_name='Статус')), ('date', models.DateField(help_text='Дата, к которой относится списание', verbose_name='Дата документа')), ('notes', models.TextField(blank=True, null=True, verbose_name='Примечания')), ('confirmed_at', models.DateTimeField(blank=True, null=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': ['-date', '-created_at'], }, ), migrations.CreateModel( name='WriteOffDocumentItem', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.DecimalField(decimal_places=3, max_digits=10, verbose_name='Количество')), ('reason', models.CharField(choices=[('damage', 'Повреждение'), ('spoilage', 'Порча'), ('shortage', 'Недостача'), ('inventory', 'Инвентаризационная недостача'), ('other', 'Другое')], default='damage', max_length=20, verbose_name='Причина списания')), ('notes', models.TextField(blank=True, null=True, verbose_name='Примечания')), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), ], options={ 'verbose_name': 'Позиция документа списания', 'verbose_name_plural': 'Позиции документа списания', 'ordering': ['id'], }, ), migrations.CreateModel( name='IncomingDocument', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('document_number', models.CharField(db_index=True, max_length=100, unique=True, verbose_name='Номер документа')), ('status', models.CharField(choices=[('draft', 'Черновик'), ('confirmed', 'Проведён'), ('cancelled', 'Отменён')], db_index=True, default='draft', max_length=20, verbose_name='Статус')), ('date', models.DateField(help_text='Дата, к которой относится поступление', verbose_name='Дата документа')), ('receipt_type', models.CharField(choices=[('supplier', 'Поступление от поставщика'), ('inventory', 'Оприходование при инвентаризации'), ('adjustment', 'Оприходование без инвентаризации')], db_index=True, default='supplier', max_length=20, verbose_name='Тип поступления')), ('supplier_name', models.CharField(blank=True, help_text="Заполняется для типа 'Поступление от поставщика'", max_length=200, null=True, verbose_name='Наименование поставщика')), ('notes', models.TextField(blank=True, null=True, verbose_name='Примечания')), ('confirmed_at', models.DateTimeField(blank=True, null=True, verbose_name='Дата проведения')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Создан')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Обновлён')), ('confirmed_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='confirmed_incoming_documents', to=settings.AUTH_USER_MODEL, verbose_name='Провёл')), ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_incoming_documents', to=settings.AUTH_USER_MODEL, verbose_name='Создал')), ], options={ 'verbose_name': 'Документ поступления', 'verbose_name_plural': 'Документы поступления', 'ordering': ['-date', '-created_at'], }, ), migrations.CreateModel( name='IncomingDocumentItem', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.DecimalField(decimal_places=3, max_digits=10, verbose_name='Количество')), ('cost_price', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Закупочная цена')), ('notes', models.TextField(blank=True, null=True, verbose_name='Примечания')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Создан')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Обновлён')), ('document', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='inventory.incomingdocument', verbose_name='Документ')), ], options={ 'verbose_name': 'Позиция документа поступления', 'verbose_name_plural': 'Позиции документа поступления', 'ordering': ['id'], }, ), ]