Добавлена модель документа списания товаров (WriteOffDocument)
- Создана модель WriteOffDocument для коллективного списания с поддержкой статусов (черновик/проведен/отменен) - Добавлена модель WriteOffDocumentItem для позиций документа - Расширена модель Reservation связью с WriteOffDocumentItem для резервирования товара в черновике - Добавлен тип счетчика 'writeoff' в DocumentCounter для автонумерации - Реализована логика резервирования товара в черновике документа (уменьшает quantity_free) - При проведении документа создаются WriteOff записи по методу FIFO
This commit is contained in:
91
myproject/inventory/migrations/0010_writeoff_document.py
Normal file
91
myproject/inventory/migrations/0010_writeoff_document.py
Normal file
@@ -0,0 +1,91 @@
|
||||
# Generated by Django 5.0.10 on 2025-12-10 19:21
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0009_fix_showcase_items_status'),
|
||||
('products', '0010_alter_product_cost_price'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='documentcounter',
|
||||
name='counter_type',
|
||||
field=models.CharField(choices=[('transfer', 'Перемещение товара'), ('writeoff', 'Списание товара')], max_length=20, unique=True, verbose_name='Тип счетчика'),
|
||||
),
|
||||
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='Обновлён')),
|
||||
('confirmed_by', 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='Провёл')),
|
||||
('created_by', 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='Создал')),
|
||||
('warehouse', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='writeoff_documents', to='inventory.warehouse', 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)),
|
||||
('document', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='inventory.writeoffdocument', verbose_name='Документ')),
|
||||
('product', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='writeoff_document_items', to='products.product', verbose_name='Товар')),
|
||||
('reservation', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='writeoff_document_item_reverse', to='inventory.reservation', verbose_name='Резерв')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Позиция документа списания',
|
||||
'verbose_name_plural': 'Позиции документа списания',
|
||||
'ordering': ['id'],
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='reservation',
|
||||
name='writeoff_document_item',
|
||||
field=models.ForeignKey(blank=True, help_text='Резерв для документа списания (черновик)', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reservations', to='inventory.writeoffdocumentitem', verbose_name='Позиция документа списания'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='writeoffdocument',
|
||||
index=models.Index(fields=['document_number'], name='inventory_w_documen_a9ae00_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='writeoffdocument',
|
||||
index=models.Index(fields=['warehouse', 'status'], name='inventory_w_warehou_69fbf6_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='writeoffdocument',
|
||||
index=models.Index(fields=['date'], name='inventory_w_date_a853cb_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='writeoffdocument',
|
||||
index=models.Index(fields=['-created_at'], name='inventory_w_created_02c298_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='writeoffdocumentitem',
|
||||
index=models.Index(fields=['document'], name='inventory_w_documen_d77c5e_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='writeoffdocumentitem',
|
||||
index=models.Index(fields=['product'], name='inventory_w_product_6e32fc_idx'),
|
||||
),
|
||||
]
|
||||
Reference in New Issue
Block a user