#!/usr/bin/env python """ Скрипт для тестирования системы наличия товаров и цен вариантов. Проверяет: 1. Обновление Product.in_stock при создании Stock 2. Свойство ProductVariantGroup.in_stock (вариант в наличии если хотя бы один товар в наличии) 3. Свойство ProductVariantGroup.price (берётся цена по приоритету) """ import os import sys import django # Добавляем путь к myproject sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'myproject')) os.chdir(os.path.join(os.path.dirname(__file__), 'myproject')) os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings') django.setup() from decimal import Decimal from products.models import Product, ProductVariantGroup, ProductVariantGroupItem from inventory.models import Stock, StockBatch, Warehouse, Incoming, IncomingBatch from django.utils import timezone def clear_data(): """Очищаем тестовые данные""" Product.objects.all().delete() ProductVariantGroup.objects.all().delete() Stock.objects.all().delete() StockBatch.objects.all().delete() Warehouse.objects.all().delete() IncomingBatch.objects.all().delete() print("OK Данные очищены") def create_test_data(): """Создаём тестовые данные""" # Создаём склад warehouse = Warehouse.objects.create( name="Основной склад", description="Тестовый склад", is_active=True, is_default=True ) print(f"OK Создан склад: {warehouse.name}") # Создаём товары (розы разной длины) products = [] prices = [Decimal('50.00'), Decimal('60.00'), Decimal('70.00')] for i, price in enumerate(prices, 1): product = Product.objects.create( name=f"Роза красная Freedom {50 + i*10}см", sku=f"ROSE-RED-{50 + i*10}", cost_price=Decimal('30.00'), sale_price=price, unit='шт', is_active=True, in_stock=False # По умолчанию нет в наличии ) products.append(product) print(f"OK Создан товар: {product.name} (цена: {price}, in_stock={product.in_stock})") # Создаём группу вариантов variant_group = ProductVariantGroup.objects.create( name="Роза красная Freedom", description="Розы разной высоты" ) print(f"OK Создана группа вариантов: {variant_group.name}") # Добавляем товары в группу с приоритетами items = [] for priority, product in enumerate(products, 1): item = ProductVariantGroupItem.objects.create( variant_group=variant_group, product=product, priority=priority ) items.append(item) print(f" - {product.name} (приоритет {priority})") return warehouse, products, variant_group, items def test_scenario_1(): """ Тест 1: Создание товара в наличии и проверка автоматического обновления in_stock """ print("\n" + "="*80) print("ТЕСТ 1: Обновление Product.in_stock при создании Stock") print("="*80) warehouse, products, variant_group, items = create_test_data() # Получаем первый товар product = products[0] print(f"\nПроверяем товар: {product.name}") print(f"Текущий статус in_stock: {product.in_stock}") # Создаём приход товара (это должно создать Stock и обновить in_stock) incoming_batch = IncomingBatch.objects.create( warehouse=warehouse, document_number="IN-0001", supplier_name="Тестовый поставщик" ) print(f"\nOK Создана партия поступления: {incoming_batch.document_number}") # Добавляем товар в приход incoming = Incoming.objects.create( batch=incoming_batch, product=product, quantity=Decimal('100.00'), cost_price=product.cost_price ) print(f"OK Добавлен товар в приход: {incoming.quantity} шт") # Проверяем что Stock был создан и in_stock обновлён stock = Stock.objects.get(product=product, warehouse=warehouse) print(f"\nOK Stock создан:") print(f" - quantity_available: {stock.quantity_available}") print(f" - quantity_reserved: {stock.quantity_reserved}") print(f" - quantity_free: {stock.quantity_free}") # Обновляем товар из БД чтобы получить новое значение product.refresh_from_db() print(f"\nOK Product.in_stock обновлён: {product.in_stock}") if product.in_stock: print("PASS: ТЕСТ 1 ПРОЙДЕН: Product.in_stock = True") else: print("FAIL: ТЕСТ 1 ПРОВАЛЕН: Product.in_stock должен быть True") return warehouse, products, variant_group, items def test_scenario_2(warehouse, products, variant_group, items): """ Тест 2: Проверка свойства ProductVariantGroup.in_stock """ print("\n" + "="*80) print("ТЕСТ 2: Свойство ProductVariantGroup.in_stock") print("="*80) # Обновляем товары из БД for product in products: product.refresh_from_db() print(f"\nГруппа вариантов: {variant_group.name}") print(f"Товары в группе:") for item in variant_group.items.all(): print(f" - {item.product.name} (приоритет {item.priority}, in_stock={item.product.in_stock})") # Первый товар в наличии, поэтому вариант должен быть в наличии print(f"\nСвойство variant_group.in_stock: {variant_group.in_stock}") if variant_group.in_stock: print("PASS: ТЕСТ 2 ПРОЙДЕН: Вариант в наличии (хотя бы один товар доступен)") else: print("FAIL: ТЕСТ 2 ПРОВАЛЕН: Вариант должен быть в наличии") def test_scenario_3(warehouse, products, variant_group, items): """ Тест 3: Проверка свойства ProductVariantGroup.price """ print("\n" + "="*80) print("ТЕСТ 3: Свойство ProductVariantGroup.price") print("="*80) print(f"\nГруппа вариантов: {variant_group.name}") # Обновляем товары из БД for product in products: product.refresh_from_db() print(f"Товары в приоритете:") for item in variant_group.items.all().order_by('priority'): status = "OK В наличии" if item.product.in_stock else "NO Нет в наличии" print(f" {item.priority}. {item.product.name} - {item.product.sale_price} руб {status}") # Цена должна быть из первого в наличии (приоритет 1, цена 50.00) price = variant_group.price expected_price = Decimal('50.00') print(f"\nЦена варианта: {price} руб") print(f"Ожидаемая цена: {expected_price} руб") if price == expected_price: print("PASS: ТЕСТ 3 ПРОЙДЕН: Берётся цена товара с приоритетом 1") else: print(f"FAIL: ТЕСТ 3 ПРОВАЛЕН: Цена должна быть {expected_price}, получена {price}") def test_scenario_4(): """ Тест 4: Проверка цены когда нет товара в наличии (должна быть максимальная) """ print("\n" + "="*80) print("ТЕСТ 4: Цена варианта когда ни один товар не в наличии") print("="*80) # Очищаем данные clear_data() # Создаём новые данные без Stock (товары не в наличии) warehouse = Warehouse.objects.create( name="Тестовый склад", is_active=True, is_default=True ) # Создаём товары с разными ценами products = [] prices = [Decimal('100.00'), Decimal('150.00'), Decimal('200.00')] for i, price in enumerate(prices, 1): product = Product.objects.create( name=f"Товар {i}", sku=f"PRODUCT-{i}", cost_price=Decimal('50.00'), sale_price=price, unit='шт', is_active=True, in_stock=False # Нет в наличии ) products.append(product) # Создаём группу вариантов variant_group = ProductVariantGroup.objects.create( name="Группа товаров без наличия" ) # Добавляем товары в группу for priority, product in enumerate(products, 1): ProductVariantGroupItem.objects.create( variant_group=variant_group, product=product, priority=priority ) print(f"\nГруппа: {variant_group.name}") print(f"Товары (все без наличия):") for item in variant_group.items.all().order_by('priority'): print(f" {item.priority}. {item.product.name} - {item.product.sale_price} руб (in_stock={item.product.in_stock})") # Цена должна быть максимальная = 200.00 price = variant_group.price expected_price = Decimal('200.00') print(f"\nЦена варианта (максимальная): {price} руб") print(f"Ожидаемая цена (максимальная): {expected_price} руб") if price == expected_price: print("PASS: ТЕСТ 4 ПРОЙДЕН: Берётся максимальная цена из товаров") else: print(f"FAIL: ТЕСТ 4 ПРОВАЛЕН: Цена должна быть {expected_price}, получена {price}") if __name__ == '__main__': print("\n" + "="*80) print("= ТЕСТИРОВАНИЕ СИСТЕМЫ НАЛИЧИЯ ТОВАРОВ И ЦЕН ВАРИАНТОВ") print("="*80) try: # Очищаем старые данные clear_data() # Тесты 1-3 warehouse, products, variant_group, items = test_scenario_1() test_scenario_2(warehouse, products, variant_group, items) test_scenario_3(warehouse, products, variant_group, items) # Тест 4 test_scenario_4() print("\n" + "="*80) print("= ТЕСТИРОВАНИЕ ЗАВЕРШЕНО") print("="*80 + "\n") except Exception as e: print(f"\nОШИБКА: {e}") import traceback traceback.print_exc()