Исправлены 4 проблемы: 1. Расчёт цены первого товара - улучшена валидация в getProductPrice и calculateFinalPrice 2. Отображение actual_price в Select2 вместо обычной цены 3. Количество по умолчанию = 1 для новых форм компонентов 4. Auto-select текста при клике на поле количества для удобства редактирования Изменённые файлы: - products/forms.py: добавлен __init__ в KitItemForm для quantity.initial = 1 - products/templates/includes/select2-product-init.html: обновлена formatSelectResult - products/templates/productkit_create.html: добавлен focus handler для auto-select - products/templates/productkit_edit.html: добавлен focus handler для auto-select 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
114 lines
3.8 KiB
Python
114 lines
3.8 KiB
Python
import os
|
||
import sys
|
||
import django
|
||
from decimal import Decimal
|
||
|
||
sys.path.insert(0, 'C:/Users/team_/Desktop/test_qwen/myproject')
|
||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
|
||
django.setup()
|
||
|
||
from tenants.models import Client
|
||
from django.db import connection
|
||
from products.models import Product
|
||
from inventory.models import Warehouse, StockBatch, Incoming, Sale
|
||
|
||
# Переключаемся в grach
|
||
grach = Client.objects.get(schema_name='grach')
|
||
connection.set_tenant(grach)
|
||
|
||
print("=== FIFO Inventory Test ===\n")
|
||
|
||
# 1. Проверяем, есть ли товары
|
||
products = Product.objects.all()
|
||
if not products.exists():
|
||
print("ERROR: No products in grach!")
|
||
sys.exit(1)
|
||
|
||
product = products.first()
|
||
print(f"Using product: {product.name} (ID: {product.id})\n")
|
||
|
||
# 2. Создаём или получаем склад
|
||
warehouse, created = Warehouse.objects.get_or_create(
|
||
name='Main Warehouse',
|
||
defaults={'location': 'Default Location', 'is_active': True}
|
||
)
|
||
print(f"Warehouse: {warehouse.name} ({'created' if created else 'exists'})\n")
|
||
|
||
# 3. Создаём 3 прихода с разными ценами (FIFO тест)
|
||
print("Creating incoming batches...")
|
||
|
||
incoming1 = Incoming.objects.create(
|
||
product=product,
|
||
warehouse=warehouse,
|
||
quantity=Decimal('10'),
|
||
cost_price=Decimal('100.00'),
|
||
notes='Batch 1 - oldest'
|
||
)
|
||
print(f" Batch 1: qty=10, price=100 (created: {incoming1.created_at})")
|
||
|
||
incoming2 = Incoming.objects.create(
|
||
product=product,
|
||
warehouse=warehouse,
|
||
quantity=Decimal('15'),
|
||
cost_price=Decimal('120.00'),
|
||
notes='Batch 2 - middle'
|
||
)
|
||
print(f" Batch 2: qty=15, price=120 (created: {incoming2.created_at})")
|
||
|
||
incoming3 = Incoming.objects.create(
|
||
product=product,
|
||
warehouse=warehouse,
|
||
quantity=Decimal('20'),
|
||
cost_price=Decimal('150.00'),
|
||
notes='Batch 3 - newest'
|
||
)
|
||
print(f" Batch 3: qty=20, price=150 (created: {incoming3.created_at})\n")
|
||
|
||
# 4. Проверяем StockBatches
|
||
batches = StockBatch.objects.filter(product=product, warehouse=warehouse).order_by('created_at')
|
||
print(f"StockBatches created: {batches.count()}")
|
||
for batch in batches:
|
||
print(f" - qty={batch.quantity}, price={batch.cost_price}, created={batch.created_at}")
|
||
|
||
print("\n--- Creating Sale ---\n")
|
||
|
||
# 5. Создаём продажу на 18 единиц (должна взять из batch1 (10) + batch2 (8))
|
||
try:
|
||
sale = Sale.objects.create(
|
||
product=product,
|
||
warehouse=warehouse,
|
||
quantity=Decimal('18'),
|
||
sale_price=Decimal('200.00'),
|
||
notes='Test sale for FIFO'
|
||
)
|
||
print(f"Sale created: qty=18, price=200\n")
|
||
|
||
# 6. Проверяем SaleBatchAllocation (как батчи были распределены)
|
||
from inventory.models import SaleBatchAllocation
|
||
|
||
allocations = SaleBatchAllocation.objects.filter(sale=sale).order_by('batch__created_at')
|
||
print(f"SaleBatchAllocations ({allocations.count()}):")
|
||
|
||
total_allocated = Decimal('0')
|
||
for alloc in allocations:
|
||
print(f" - Batch (created {alloc.batch.created_at.strftime('%H:%M:%S')}): qty={alloc.quantity}, cost={alloc.batch.cost_price}")
|
||
total_allocated += alloc.quantity
|
||
|
||
print(f"\nTotal allocated: {total_allocated}")
|
||
|
||
if total_allocated == Decimal('18'):
|
||
print("✓ FIFO allocation correct!")
|
||
else:
|
||
print(f"✗ ERROR: Expected 18, got {total_allocated}")
|
||
|
||
except Exception as e:
|
||
print(f"ERROR creating sale: {str(e)}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
# 7. Проверяем оставшиеся батчи
|
||
print("\n--- Remaining Stock ---\n")
|
||
remaining_batches = StockBatch.objects.filter(product=product, warehouse=warehouse).order_by('created_at')
|
||
for batch in remaining_batches:
|
||
print(f" - Batch qty={batch.quantity}, active={batch.is_active}")
|