diff --git a/myproject/inventory/signals.py b/myproject/inventory/signals.py index 606f5fe..ec2f4e4 100644 --- a/myproject/inventory/signals.py +++ b/myproject/inventory/signals.py @@ -222,9 +222,14 @@ def reserve_stock_on_item_create(sender, instance, created, **kwargs): for kit_item in instance.kit_snapshot.items.select_related('original_product'): if kit_item.original_product: - # Суммируем количество: qty компонента * qty комплектов в заказе + # Рассчитываем количество одного компонента в базовых единицах + component_qty_base = kit_item.quantity + if kit_item.conversion_factor and kit_item.conversion_factor > 0: + component_qty_base = kit_item.quantity / kit_item.conversion_factor + + # Суммируем количество: qty компонента (base) * qty комплектов в заказе product_quantities[kit_item.original_product_id] += ( - kit_item.quantity * Decimal(str(instance.quantity)) + component_qty_base * Decimal(str(instance.quantity)) ) # Создаём по одному резерву на каждый уникальный товар diff --git a/myproject/orders/migrations/0004_kititemsnapshot_conversion_factor_and_more.py b/myproject/orders/migrations/0004_kititemsnapshot_conversion_factor_and_more.py new file mode 100644 index 0000000..bd46014 --- /dev/null +++ b/myproject/orders/migrations/0004_kititemsnapshot_conversion_factor_and_more.py @@ -0,0 +1,25 @@ +# Generated by Django 5.0.10 on 2026-01-21 07:27 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('orders', '0003_order_summary'), + ('products', '0001_add_sales_unit_to_kititem'), + ] + + operations = [ + migrations.AddField( + model_name='kititemsnapshot', + name='conversion_factor', + field=models.DecimalField(blank=True, decimal_places=6, help_text='Сколько единиц продажи в 1 базовой единице товара', max_digits=15, null=True, verbose_name='Коэффициент конверсии'), + ), + migrations.AddField( + model_name='kititemsnapshot', + name='original_sales_unit', + field=models.ForeignKey(blank=True, help_text='Единица продажи на момент создания снимка', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='kit_item_snapshots', to='products.productsalesunit', verbose_name='Единица продажи'), + ), + ] diff --git a/myproject/orders/models/kit_snapshot.py b/myproject/orders/models/kit_snapshot.py index 1957338..fdc85a9 100644 --- a/myproject/orders/models/kit_snapshot.py +++ b/myproject/orders/models/kit_snapshot.py @@ -140,6 +140,25 @@ class KitItemSnapshot(models.Model): verbose_name="Группа вариантов" ) + original_sales_unit = models.ForeignKey( + 'products.ProductSalesUnit', + on_delete=models.SET_NULL, + null=True, + blank=True, + related_name='kit_item_snapshots', + verbose_name="Единица продажи", + help_text="Единица продажи на момент создания снимка" + ) + + conversion_factor = models.DecimalField( + max_digits=15, + decimal_places=6, + null=True, + blank=True, + verbose_name="Коэффициент конверсии", + help_text="Сколько единиц продажи в 1 базовой единице товара" + ) + quantity = models.DecimalField( max_digits=10, decimal_places=3, diff --git a/myproject/products/models/kits.py b/myproject/products/models/kits.py index 76eb1d4..bc899b0 100644 --- a/myproject/products/models/kits.py +++ b/myproject/products/models/kits.py @@ -382,6 +382,8 @@ class ProductKit(BaseProductEntity): product_sku=item.product.sku if item.product else '', product_price=product_price, variant_group_name=item.variant_group.name if item.variant_group else '', + original_sales_unit=item.sales_unit, + conversion_factor=item.sales_unit.conversion_factor if item.sales_unit else None, quantity=item.quantity or Decimal('1'), ) diff --git a/myproject/products/templates/products/productkit_edit.html b/myproject/products/templates/products/productkit_edit.html index fb41fdd..b69a4b6 100644 --- a/myproject/products/templates/products/productkit_edit.html +++ b/myproject/products/templates/products/productkit_edit.html @@ -725,6 +725,9 @@ // Функция для обновления списка единиц продажи при выборе товара async function updateSalesUnitsOptions(salesUnitSelect, productValue) { + // Сохраняем текущее значение перед очисткой (важно для редактирования) + const currentValue = salesUnitSelect.value; + // Очищаем текущие опции salesUnitSelect.innerHTML = ''; salesUnitSelect.disabled = true; @@ -765,6 +768,13 @@ salesUnitSelect.appendChild(option); }); salesUnitSelect.disabled = false; + + // Восстанавливаем значение + if (currentValue) { + salesUnitSelect.value = currentValue; + } + // Обновляем Select2 + $(salesUnitSelect).trigger('change'); } } } catch (error) { @@ -1214,7 +1224,7 @@ photoPreview.innerHTML = ''; } }); - } + }; window.removePhoto = function (index) { selectedFiles.splice(index, 1); diff --git a/prepare_js.py b/prepare_js.py new file mode 100644 index 0000000..428a822 --- /dev/null +++ b/prepare_js.py @@ -0,0 +1,29 @@ + +import re + +file_path = r'c:\Users\team_\Desktop\test_qwen\myproject\products\templates\products\productkit_edit.html' + +try: + with open(file_path, 'r', encoding='utf-8') as f: + lines = f.readlines() +except FileNotFoundError: + print(f"File not found: {file_path}") + exit(1) + +# Extract script part (approx lines 451 to 1321) +# Note: lines are 0-indexed in list +script_lines = lines[450:1322] +script_content = "".join(script_lines) + +# Replace Django tags +# Replace {% ... %} with "TEMPLATETAG" +script_content = re.sub(r'\{%.*?%\}', '"TEMPLATETAG"', script_content) +# Replace {{ ... }} with "VARIABLE" or {} +script_content = re.sub(r'\{\{.*?\}\}', '{}', script_content) + +# Save to temp js file +temp_js_path = r'c:\Users\team_\Desktop\test_qwen\temp_check.js' +with open(temp_js_path, 'w', encoding='utf-8') as f: + f.write(script_content) + +print(f"Written to {temp_js_path}")