fix: Улучшения системы ценообразования комплектов
Исправлены 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>
This commit is contained in:
105
test_fifo.py
Normal file
105
test_fifo.py
Normal file
@@ -0,0 +1,105 @@
|
||||
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, Incoming, Sale, SaleBatchAllocation, StockBatch
|
||||
|
||||
# Переключаемся в grach
|
||||
grach = Client.objects.get(schema_name='grach')
|
||||
connection.set_tenant(grach)
|
||||
|
||||
print("=== FIFO Test ===\n")
|
||||
|
||||
# Получаем товар и склад
|
||||
product = Product.objects.get(sku='FLOWER-001')
|
||||
warehouse = Warehouse.objects.get(name='Main Warehouse')
|
||||
|
||||
print("Step 1: Creating 3 incoming batches\n")
|
||||
|
||||
# Создаём 3 прихода
|
||||
incoming1 = Incoming.objects.create(
|
||||
product=product,
|
||||
warehouse=warehouse,
|
||||
quantity=Decimal('10'),
|
||||
cost_price=Decimal('100.00')
|
||||
)
|
||||
print(" Incoming 1: qty=10, cost=100.00")
|
||||
|
||||
incoming2 = Incoming.objects.create(
|
||||
product=product,
|
||||
warehouse=warehouse,
|
||||
quantity=Decimal('15'),
|
||||
cost_price=Decimal('120.00')
|
||||
)
|
||||
print(" Incoming 2: qty=15, cost=120.00")
|
||||
|
||||
incoming3 = Incoming.objects.create(
|
||||
product=product,
|
||||
warehouse=warehouse,
|
||||
quantity=Decimal('20'),
|
||||
cost_price=Decimal('150.00')
|
||||
)
|
||||
print(" Incoming 3: qty=20, cost=150.00\n")
|
||||
|
||||
print("Step 2: Checking StockBatches\n")
|
||||
|
||||
batches = StockBatch.objects.filter(product=product, warehouse=warehouse).order_by('created_at')
|
||||
print("StockBatches count: {}\n".format(batches.count()))
|
||||
|
||||
for i, batch in enumerate(batches, 1):
|
||||
print(" Batch {}: qty={}, cost={}, active={}".format(i, batch.quantity, batch.cost_price, batch.is_active))
|
||||
|
||||
print("\nStep 3: Creating Sale (qty=18)\n")
|
||||
|
||||
try:
|
||||
sale = Sale.objects.create(
|
||||
product=product,
|
||||
warehouse=warehouse,
|
||||
quantity=Decimal('18'),
|
||||
sale_price=Decimal('250.00')
|
||||
)
|
||||
print("Sale created: qty=18, price=250.00\n")
|
||||
|
||||
print("Step 4: Checking SaleBatchAllocations\n")
|
||||
|
||||
allocations = SaleBatchAllocation.objects.filter(sale=sale).order_by('batch__created_at')
|
||||
total = Decimal('0')
|
||||
|
||||
for i, alloc in enumerate(allocations, 1):
|
||||
print(" Allocation {}: qty={}, batch_cost={}".format(i, alloc.quantity, alloc.batch.cost_price))
|
||||
total += alloc.quantity
|
||||
|
||||
print("\nTotal allocated: {}".format(total))
|
||||
|
||||
if total == Decimal('18'):
|
||||
print("PASS: Correct total")
|
||||
else:
|
||||
print("FAIL: Expected 18, got {}".format(total))
|
||||
|
||||
# Check FIFO order
|
||||
expected_order = [Decimal('10'), Decimal('8')]
|
||||
actual_order = [alloc.quantity for alloc in allocations]
|
||||
|
||||
if actual_order == expected_order:
|
||||
print("PASS: FIFO order correct (batch1 10 + batch2 8)")
|
||||
else:
|
||||
print("FAIL: Expected {}, got {}".format(expected_order, actual_order))
|
||||
|
||||
except Exception as e:
|
||||
print("ERROR: {}".format(str(e)))
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
print("\nStep 5: Checking remaining stock\n")
|
||||
|
||||
remaining = StockBatch.objects.filter(product=product, warehouse=warehouse).order_by('created_at')
|
||||
for i, batch in enumerate(remaining, 1):
|
||||
print(" Batch {}: qty={}, active={}".format(i, batch.quantity, batch.is_active))
|
||||
Reference in New Issue
Block a user