Обновления в inventory: модели, миграции и удаление старых миграций

This commit is contained in:
2026-01-08 22:11:23 +03:00
parent 1069039953
commit 2d1f8b78ad
6 changed files with 27 additions and 87 deletions

View File

@@ -1,8 +1,8 @@
# Generated by Django 5.0.10 on 2026-01-03 23:23 # Generated by Django 5.0.10 on 2026-01-08 15:58
import django.db.models.deletion import django.db.models.deletion
import phonenumber_field.modelfields import phonenumber_field.modelfields
from django.conf import settings from decimal import Decimal
from django.db import migrations, models from django.db import migrations, models
@@ -11,7 +11,7 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('accounts', '0001_initial'),
] ]
operations = [ operations = [
@@ -71,6 +71,7 @@ class Migration(migrations.Migration):
('converted_at', models.DateTimeField(blank=True, help_text='Дата преобразования в продажу или списание', 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_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 сессии корзины')), ('cart_session_id', models.CharField(blank=True, help_text='Дополнительная идентификация сессии для надежности', max_length=100, null=True, verbose_name='ID сессии корзины')),
('original_order_item_id', models.IntegerField(blank=True, db_index=True, help_text='Для витринных резервов: ID OrderItem, которому изначально принадлежал резерв (защита от кражи)', null=True, verbose_name='ID исходной позиции заказа')),
('quantity_base', models.DecimalField(blank=True, decimal_places=6, help_text='Количество в единицах хранения товара', max_digits=10, null=True, verbose_name='Количество в базовых единицах')), ('quantity_base', models.DecimalField(blank=True, decimal_places=6, help_text='Количество в единицах хранения товара', max_digits=10, null=True, verbose_name='Количество в базовых единицах')),
], ],
options={ options={
@@ -90,6 +91,8 @@ class Migration(migrations.Migration):
('processed', models.BooleanField(default=False, verbose_name='Обработана (FIFO применена)')), ('processed', models.BooleanField(default=False, verbose_name='Обработана (FIFO применена)')),
('quantity_base', models.DecimalField(blank=True, decimal_places=6, help_text='Количество в единицах хранения товара (для списания со склада)', max_digits=10, null=True, verbose_name='Количество в базовых единицах')), ('quantity_base', models.DecimalField(blank=True, decimal_places=6, help_text='Количество в единицах хранения товара (для списания со склада)', max_digits=10, null=True, verbose_name='Количество в базовых единицах')),
('unit_name_snapshot', models.CharField(blank=True, default='', help_text='Название единицы продажи на момент продажи', max_length=100, verbose_name='Название единицы (snapshot)')), ('unit_name_snapshot', models.CharField(blank=True, default='', help_text='Название единицы продажи на момент продажи', max_length=100, verbose_name='Название единицы (snapshot)')),
('is_pending_cost', models.BooleanField(default=False, help_text="True если продажа создана без партий (продажа 'в минус')", verbose_name='Ожидает себестоимости')),
('pending_quantity', models.DecimalField(decimal_places=3, default=Decimal('0'), help_text='Количество, ожидающее привязки к партиям при приёмке', max_digits=10, verbose_name='Ожидающее количество')),
], ],
options={ options={
'verbose_name': 'Продажа', 'verbose_name': 'Продажа',
@@ -130,7 +133,7 @@ class Migration(migrations.Migration):
name='ShowcaseItem', name='ShowcaseItem',
fields=[ fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('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='Статус')), ('status', models.CharField(choices=[('available', 'Доступен'), ('in_cart', 'В корзине'), ('reserved', 'Зарезервирован'), ('sold', 'Продан'), ('dismantled', 'Разобран')], db_index=True, default='available', max_length=20, verbose_name='Статус')),
('sold_at', models.DateTimeField(blank=True, null=True, 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_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 сессии корзины')), ('cart_session_id', models.CharField(blank=True, max_length=100, null=True, verbose_name='ID сессии корзины')),
@@ -322,8 +325,8 @@ class Migration(migrations.Migration):
('confirmed_at', models.DateTimeField(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='Создан')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Создан')),
('updated_at', models.DateTimeField(auto_now=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='Провёл')), ('confirmed_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='confirmed_incoming_documents', to='accounts.customuser', 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='Создал')), ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_incoming_documents', to='accounts.customuser', verbose_name='Создал')),
], ],
options={ options={
'verbose_name': 'Документ поступления', 'verbose_name': 'Документ поступления',

View File

@@ -1,7 +1,6 @@
# Generated by Django 5.0.10 on 2026-01-03 23:23 # Generated by Django 5.0.10 on 2026-01-08 15:58
import django.db.models.deletion import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
@@ -10,11 +9,11 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
('accounts', '0001_initial'),
('inventory', '0001_initial'), ('inventory', '0001_initial'),
('orders', '0001_initial'), ('orders', '0001_initial'),
('products', '0001_initial'), ('products', '0001_initial'),
('user_roles', '0001_initial'), ('user_roles', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
] ]
operations = [ operations = [
@@ -46,7 +45,7 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='reservation', model_name='reservation',
name='locked_by_user', name='locked_by_user',
field=models.ForeignKey(blank=True, help_text='Кассир, который добавил комплект в корзину', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='cart_locks', to=settings.AUTH_USER_MODEL, verbose_name='Заблокировано пользователем'), field=models.ForeignKey(blank=True, help_text='Кассир, который добавил комплект в корзину', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='cart_locks', to='accounts.customuser', verbose_name='Заблокировано пользователем'),
), ),
migrations.AddField( migrations.AddField(
model_name='reservation', model_name='reservation',
@@ -96,7 +95,7 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='showcaseitem', model_name='showcaseitem',
name='locked_by_user', name='locked_by_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='locked_showcase_items', to=settings.AUTH_USER_MODEL, verbose_name='Заблокировано пользователем'), field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='locked_showcase_items', to='accounts.customuser', verbose_name='Заблокировано пользователем'),
), ),
migrations.AddField( migrations.AddField(
model_name='showcaseitem', model_name='showcaseitem',
@@ -156,7 +155,7 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='transformation', model_name='transformation',
name='employee', name='employee',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='transformations', to=settings.AUTH_USER_MODEL, verbose_name='Сотрудник'), field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='transformations', to='accounts.customuser', verbose_name='Сотрудник'),
), ),
migrations.AddField( migrations.AddField(
model_name='transformationinput', model_name='transformationinput',
@@ -258,12 +257,12 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='writeoffdocument', model_name='writeoffdocument',
name='confirmed_by', name='confirmed_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='confirmed_writeoff_documents', to=settings.AUTH_USER_MODEL, verbose_name='Провёл'), field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='confirmed_writeoff_documents', to='accounts.customuser', verbose_name='Провёл'),
), ),
migrations.AddField( migrations.AddField(
model_name='writeoffdocument', model_name='writeoffdocument',
name='created_by', name='created_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_writeoff_documents', to=settings.AUTH_USER_MODEL, verbose_name='Создал'), field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_writeoff_documents', to='accounts.customuser', verbose_name='Создал'),
), ),
migrations.AddField( migrations.AddField(
model_name='writeoffdocument', model_name='writeoffdocument',
@@ -399,6 +398,10 @@ class Migration(migrations.Migration):
model_name='sale', model_name='sale',
index=models.Index(fields=['order'], name='inventory_s_order_i_7d13ea_idx'), index=models.Index(fields=['order'], name='inventory_s_order_i_7d13ea_idx'),
), ),
migrations.AddIndex(
model_name='sale',
index=models.Index(fields=['is_pending_cost'], name='inventory_s_is_pend_81a3db_idx'),
),
migrations.AddIndex( migrations.AddIndex(
model_name='inventory', model_name='inventory',
index=models.Index(fields=['document_number'], name='inventory_i_documen_8df782_idx'), index=models.Index(fields=['document_number'], name='inventory_i_documen_8df782_idx'),

View File

@@ -1,30 +0,0 @@
# Generated by Django 5.0.10 on 2026-01-04 06:53
from decimal import Decimal
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventory', '0002_initial'),
('orders', '0002_initial'),
('products', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='sale',
name='is_pending_cost',
field=models.BooleanField(default=False, help_text="True если продажа создана без партий (продажа 'в минус')", verbose_name='Ожидает себестоимости'),
),
migrations.AddField(
model_name='sale',
name='pending_quantity',
field=models.DecimalField(decimal_places=3, default=Decimal('0'), help_text='Количество, ожидающее привязки к партиям при приёмке', max_digits=10, verbose_name='Ожидающее количество'),
),
migrations.AddIndex(
model_name='sale',
index=models.Index(fields=['is_pending_cost'], name='inventory_s_is_pend_81a3db_idx'),
),
]

View File

@@ -1,18 +0,0 @@
# Generated by Django 5.0.10 on 2026-01-04 21:29
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventory', '0003_sale_pending_fields'),
]
operations = [
migrations.AlterField(
model_name='showcaseitem',
name='status',
field=models.CharField(choices=[('available', 'Доступен'), ('in_cart', 'В корзине'), ('reserved', 'Зарезервирован'), ('sold', 'Продан'), ('dismantled', 'Разобран')], db_index=True, default='available', max_length=20, verbose_name='Статус'),
),
]

View File

@@ -1,18 +0,0 @@
# Generated by Django 5.0.10 on 2026-01-05 10:42
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventory', '0004_add_reserved_status_to_showcaseitem'),
]
operations = [
migrations.AddField(
model_name='reservation',
name='original_order_item_id',
field=models.IntegerField(blank=True, db_index=True, help_text='Для витринных резервов: ID OrderItem, которому изначально принадлежал резерв (защита от кражи)', null=True, verbose_name='ID исходной позиции заказа'),
),
]

View File

@@ -463,7 +463,7 @@ class Reservation(models.Model):
help_text="Время истечения блокировки в корзине (для витринных комплектов)" help_text="Время истечения блокировки в корзине (для витринных комплектов)"
) )
locked_by_user = models.ForeignKey( locked_by_user = models.ForeignKey(
settings.AUTH_USER_MODEL, 'accounts.CustomUser',
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
null=True, blank=True, null=True, blank=True,
related_name='cart_locks', related_name='cart_locks',
@@ -626,7 +626,7 @@ class ShowcaseItem(models.Model):
# === SOFT LOCK для корзины === # === SOFT LOCK для корзины ===
locked_by_user = models.ForeignKey( locked_by_user = models.ForeignKey(
settings.AUTH_USER_MODEL, 'accounts.CustomUser',
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
null=True, null=True,
blank=True, blank=True,
@@ -1087,7 +1087,7 @@ class WriteOffDocument(models.Model):
# Аудит # Аудит
created_by = models.ForeignKey( created_by = models.ForeignKey(
settings.AUTH_USER_MODEL, 'accounts.CustomUser',
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
null=True, null=True,
blank=True, blank=True,
@@ -1096,7 +1096,7 @@ class WriteOffDocument(models.Model):
) )
confirmed_by = models.ForeignKey( confirmed_by = models.ForeignKey(
settings.AUTH_USER_MODEL, 'accounts.CustomUser',
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
null=True, null=True,
blank=True, blank=True,
@@ -1317,7 +1317,7 @@ class IncomingDocument(models.Model):
# Аудит # Аудит
created_by = models.ForeignKey( created_by = models.ForeignKey(
settings.AUTH_USER_MODEL, 'accounts.CustomUser',
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
null=True, null=True,
blank=True, blank=True,
@@ -1326,7 +1326,7 @@ class IncomingDocument(models.Model):
) )
confirmed_by = models.ForeignKey( confirmed_by = models.ForeignKey(
settings.AUTH_USER_MODEL, 'accounts.CustomUser',
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
null=True, null=True,
blank=True, blank=True,
@@ -1491,7 +1491,7 @@ class Transformation(models.Model):
) )
employee = models.ForeignKey( employee = models.ForeignKey(
settings.AUTH_USER_MODEL, 'accounts.CustomUser',
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
null=True, null=True,
blank=True, blank=True,