Рефакторинг: отделение Delivery от Order, обязательные поля доставки, исправление доменов
- Отделена модель Delivery от Order (OneToOne связь) - Добавлены обязательные поля delivery_date, time_from, time_to в Delivery - Delivery обязательна при создании заказа (кроме черновиков) - Добавлены методы calculate_total() и reset_delivery_cost() в Order - Добавлена валидация полей доставки в OrderForm - Исправлено создание доменов - убран порт из домена в БД - Исправлен редирект после установки пароля (правильный формат URL) - Исправлена ошибка NoReverseMatch в navbar для public схемы - Удалены все старые миграции (база создается с нуля) - Обновлены views для работы с новой моделью Delivery
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
# Generated by Django 5.0.10 on 2025-11-15 11:57
|
||||
# Generated by Django 5.0.10 on 2025-12-23 20:38
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
@@ -12,6 +13,8 @@ class Migration(migrations.Migration):
|
||||
('inventory', '0001_initial'),
|
||||
('orders', '0001_initial'),
|
||||
('products', '0001_initial'),
|
||||
('user_roles', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
@@ -25,6 +28,36 @@ class Migration(migrations.Migration):
|
||||
name='batch',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='inventory.incomingbatch', verbose_name='Партия'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='incomingdocument',
|
||||
name='confirmed_by',
|
||||
field=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='Провёл'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='incomingdocument',
|
||||
name='created_by',
|
||||
field=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='Создал'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='incomingdocumentitem',
|
||||
name='document',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='inventory.incomingdocument', verbose_name='Документ'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='incomingdocumentitem',
|
||||
name='product',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='incoming_document_items', to='products.product', verbose_name='Товар'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='inventory',
|
||||
name='conducted_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='inventories', to='user_roles.userrole', verbose_name='Провел инвентаризацию'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='incomingdocument',
|
||||
name='inventory',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='incoming_documents', to='inventory.inventory', verbose_name='Инвентаризация'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='inventoryline',
|
||||
name='inventory',
|
||||
@@ -35,6 +68,11 @@ class Migration(migrations.Migration):
|
||||
name='product',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='products.product', verbose_name='Товар'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='reservation',
|
||||
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='Заблокировано пользователем'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='reservation',
|
||||
name='order_item',
|
||||
@@ -45,6 +83,11 @@ class Migration(migrations.Migration):
|
||||
name='product',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reservations', to='products.product', verbose_name='Товар'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='reservation',
|
||||
name='product_kit',
|
||||
field=models.ForeignKey(blank=True, help_text='Временный комплект, для которого создан резерв', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reservations', to='products.productkit', verbose_name='Комплект'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='sale',
|
||||
name='order',
|
||||
@@ -60,6 +103,36 @@ class Migration(migrations.Migration):
|
||||
name='sale',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='batch_allocations', to='inventory.sale', verbose_name='Продажа'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='reservation',
|
||||
name='showcase',
|
||||
field=models.ForeignKey(blank=True, help_text='Витрина, на которой выложен букет', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reservations', to='inventory.showcase', verbose_name='Витрина'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='showcaseitem',
|
||||
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='Заблокировано пользователем'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='showcaseitem',
|
||||
name='product_kit',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='showcase_items', to='products.productkit', verbose_name='Шаблон комплекта'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='showcaseitem',
|
||||
name='showcase',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='showcase_items', to='inventory.showcase', verbose_name='Витрина'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='showcaseitem',
|
||||
name='sold_order_item',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sold_showcase_items', to='orders.orderitem', verbose_name='Позиция заказа (продажа)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='reservation',
|
||||
name='showcase_item',
|
||||
field=models.ForeignKey(blank=True, help_text='Для какого физического экземпляра создан резерв', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reservations', to='inventory.showcaseitem', verbose_name='Экземпляр на витрине'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='stock',
|
||||
name='product',
|
||||
@@ -162,6 +235,11 @@ class Migration(migrations.Migration):
|
||||
name='warehouse',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='stocks', to='inventory.warehouse', verbose_name='Склад'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='showcase',
|
||||
name='warehouse',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='showcases', to='inventory.warehouse', verbose_name='Склад'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='sale',
|
||||
name='warehouse',
|
||||
@@ -177,6 +255,11 @@ class Migration(migrations.Migration):
|
||||
name='warehouse',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='inventories', to='inventory.warehouse', verbose_name='Склад'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='incomingdocument',
|
||||
name='warehouse',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='incoming_documents', to='inventory.warehouse', verbose_name='Склад'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='incomingbatch',
|
||||
name='warehouse',
|
||||
@@ -187,6 +270,70 @@ class Migration(migrations.Migration):
|
||||
name='batch',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='writeoffs', to='inventory.stockbatch', verbose_name='Партия'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='writeoffdocument',
|
||||
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='Провёл'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='writeoffdocument',
|
||||
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='Создал'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='writeoffdocument',
|
||||
name='inventory',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='writeoff_documents', to='inventory.inventory', verbose_name='Инвентаризация'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='writeoffdocument',
|
||||
name='warehouse',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='writeoff_documents', to='inventory.warehouse', verbose_name='Склад'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='writeoffdocumentitem',
|
||||
name='document',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='inventory.writeoffdocument', verbose_name='Документ'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='writeoffdocumentitem',
|
||||
name='product',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='writeoff_document_items', to='products.product', verbose_name='Товар'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='writeoffdocumentitem',
|
||||
name='reservation',
|
||||
field=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='Резерв'),
|
||||
),
|
||||
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='incomingdocumentitem',
|
||||
index=models.Index(fields=['document'], name='inventory_i_documen_96d470_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='incomingdocumentitem',
|
||||
index=models.Index(fields=['product'], name='inventory_i_product_932432_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='showcaseitem',
|
||||
index=models.Index(fields=['showcase', 'status'], name='inventory_s_showcas_116f7f_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='showcaseitem',
|
||||
index=models.Index(fields=['product_kit', 'status'], name='inventory_s_product_785870_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='showcaseitem',
|
||||
index=models.Index(fields=['status', 'cart_lock_expires_at'], name='inventory_s_status_6acf05_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='showcaseitem',
|
||||
index=models.Index(fields=['locked_by_user', 'status'], name='inventory_s_locked__88eac9_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='incoming',
|
||||
index=models.Index(fields=['batch'], name='inventory_i_batch_i_c50b63_idx'),
|
||||
@@ -263,6 +410,18 @@ class Migration(migrations.Migration):
|
||||
name='stock',
|
||||
unique_together={('product', 'warehouse')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='showcase',
|
||||
index=models.Index(fields=['warehouse'], name='inventory_s_warehou_1e4a8a_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='showcase',
|
||||
index=models.Index(fields=['is_active'], name='inventory_s_is_acti_387bfb_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='showcase',
|
||||
index=models.Index(fields=['is_default'], name='inventory_s_is_defa_bf9a7c_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='sale',
|
||||
index=models.Index(fields=['product', 'warehouse'], name='inventory_s_product_084314_idx'),
|
||||
@@ -275,6 +434,78 @@ class Migration(migrations.Migration):
|
||||
model_name='sale',
|
||||
index=models.Index(fields=['order'], name='inventory_s_order_i_7d13ea_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='inventory',
|
||||
index=models.Index(fields=['document_number'], name='inventory_i_documen_8df782_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='incomingdocument',
|
||||
index=models.Index(fields=['document_number'], name='inventory_i_documen_5b89ad_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='incomingdocument',
|
||||
index=models.Index(fields=['warehouse', 'status'], name='inventory_i_warehou_8f141d_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='incomingdocument',
|
||||
index=models.Index(fields=['date'], name='inventory_i_date_8ace9b_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='incomingdocument',
|
||||
index=models.Index(fields=['receipt_type'], name='inventory_i_receipt_92f322_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='incomingdocument',
|
||||
index=models.Index(fields=['-created_at'], name='inventory_i_created_174930_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='incomingbatch',
|
||||
index=models.Index(fields=['document_number'], name='inventory_i_documen_679096_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='incomingbatch',
|
||||
index=models.Index(fields=['warehouse'], name='inventory_i_warehou_cc3a73_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='incomingbatch',
|
||||
index=models.Index(fields=['receipt_type'], name='inventory_i_receipt_ce70c1_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='incomingbatch',
|
||||
index=models.Index(fields=['-created_at'], name='inventory_i_created_59ee8b_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='writeoff',
|
||||
index=models.Index(fields=['batch'], name='inventory_w_batch_i_b098ce_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='writeoff',
|
||||
index=models.Index(fields=['date'], name='inventory_w_date_70c7e3_idx'),
|
||||
),
|
||||
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'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='reservation',
|
||||
index=models.Index(fields=['product', 'warehouse'], name='inventory_r_product_fa0d33_idx'),
|
||||
@@ -288,23 +519,27 @@ class Migration(migrations.Migration):
|
||||
index=models.Index(fields=['order_item'], name='inventory_r_order_i_ae991f_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='incomingbatch',
|
||||
index=models.Index(fields=['document_number'], name='inventory_i_documen_679096_idx'),
|
||||
model_name='reservation',
|
||||
index=models.Index(fields=['showcase'], name='inventory_r_showcas_bd3508_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='incomingbatch',
|
||||
index=models.Index(fields=['warehouse'], name='inventory_i_warehou_cc3a73_idx'),
|
||||
model_name='reservation',
|
||||
index=models.Index(fields=['product_kit'], name='inventory_r_product_70aed5_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='incomingbatch',
|
||||
index=models.Index(fields=['-created_at'], name='inventory_i_created_59ee8b_idx'),
|
||||
model_name='reservation',
|
||||
index=models.Index(fields=['cart_lock_expires_at'], name='inventory_r_cart_lo_e9b52a_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='writeoff',
|
||||
index=models.Index(fields=['batch'], name='inventory_w_batch_i_b098ce_idx'),
|
||||
model_name='reservation',
|
||||
index=models.Index(fields=['locked_by_user'], name='inventory_r_locked__706cbf_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='writeoff',
|
||||
index=models.Index(fields=['date'], name='inventory_w_date_70c7e3_idx'),
|
||||
model_name='reservation',
|
||||
index=models.Index(fields=['product_kit', 'cart_lock_expires_at'], name='inventory_r_product_5dacdf_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='reservation',
|
||||
index=models.Index(fields=['showcase_item'], name='inventory_r_showcas_8cfff5_idx'),
|
||||
),
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user