Files
octopus/myproject/orders/management/commands/create_demo_orders.py
Andrey Smakotin 0973121b39 Удалена устаревшая логика адресов клиентов
Исправлена ошибка AttributeError при создании нового клиента.
Адреса теперь привязаны к заказам, а не к клиентам.

- Удалено обращение к customer.addresses в customer_detail view
- Убрана секция "Адреса доставки" из шаблона customer_detail.html
- Исправлена команда create_demo_orders для работы с новой структурой

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 17:04:20 +03:00

203 lines
9.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Management команда для создания демо-заказов на разные даты
ВАЖНО: Создает заказы через Django ORM, что автоматически активирует
сигналы резервирования товаров!
"""
from django.core.management.base import BaseCommand
from django.utils import timezone
from django.db import connection
from datetime import datetime, timedelta
import random
from decimal import Decimal
from orders.models import Order, OrderItem, Address
from customers.models import Customer
from shops.models import Shop
from products.models import Product
class Command(BaseCommand):
help = 'Создает демо-заказы через ORM (с автоматическим резервированием товаров)'
def add_arguments(self, parser):
parser.add_argument(
'--count',
type=int,
default=25,
help='Количество заказов для создания (по умолчанию: 25)'
)
parser.add_argument(
'--schema',
type=str,
default='grach',
help='Схема базы данных (tenant) для создания заказов'
)
def handle(self, *args, **options):
count = options['count']
schema_name = options['schema']
# Устанавливаем схему для работы с tenant
with connection.cursor() as cursor:
cursor.execute(f'SET search_path TO {schema_name}')
self.stdout.write(f'[НАЧАЛО] Создание {count} демо-заказов в схеме {schema_name}...')
self.stdout.write('[INFO] Заказы создаются через ORM - резервы товаров будут созданы автоматически!')
# Проверяем наличие необходимых данных
customers = list(Customer.objects.all())
if not customers:
self.stdout.write(self.style.ERROR('Нет клиентов в базе! Создайте хотя бы одного клиента.'))
return
products = list(Product.objects.all())
if not products:
self.stdout.write(self.style.ERROR('Нет товаров в базе! Создайте хотя бы один товар.'))
return
addresses = list(Address.objects.all())
shops = list(Shop.objects.all())
if not addresses and not shops:
self.stdout.write(self.style.ERROR('Нет ни адресов, ни магазинов! Создайте хотя бы что-то одно.'))
return
# Статусы и их вероятности
statuses = [
('new', 0.15),
('confirmed', 0.25),
('in_assembly', 0.20),
('in_delivery', 0.15),
('delivered', 0.20),
('cancelled', 0.05),
]
payment_statuses = [
('unpaid', 0.30),
('partial', 0.20),
('paid', 0.50),
]
payment_methods = [
'cash_to_courier',
'card_to_courier',
'online',
'bank_transfer',
]
# Генерируем даты в диапазоне ±15 дней от сегодня
today = datetime.now().date()
created_count = 0
for i in range(count):
try:
# Случайная дата доставки
days_offset = random.randint(-15, 15)
delivery_date = today + timedelta(days=days_offset)
# Выбираем клиента
customer = random.choice(customers)
# Выбираем тип доставки
is_delivery = random.choice([True, False]) if addresses and shops else bool(addresses)
# Создаем заказ
order = Order()
order.customer = customer
order.is_delivery = is_delivery
# Устанавливаем адрес или магазин
if is_delivery and addresses:
# Для доставки выбираем случайный адрес (адреса теперь привязаны к заказам)
order.delivery_address = random.choice(addresses)
order.delivery_cost = Decimal(random.randint(200, 500))
elif shops:
order.pickup_shop = random.choice(shops)
order.delivery_cost = Decimal(0)
# Дата и время
order.delivery_date = delivery_date
if random.random() > 0.3: # 70% заказов с указанным временем
start_hour = random.randint(9, 18)
order.delivery_time_start = f"{start_hour:02d}:00:00"
order.delivery_time_end = f"{start_hour + 2:02d}:00:00"
# Статус
status_choices = [s[0] for s in statuses]
status_weights = [s[1] for s in statuses]
order.status = random.choices(status_choices, weights=status_weights)[0]
# Способ оплаты
order.payment_method = random.choice(payment_methods)
# Дополнительная информация
if random.random() > 0.7: # 30% - подарок другому человеку
order.customer_is_recipient = False
order.recipient_name = f"Получатель {i+1}"
order.recipient_phone = f"+7{random.randint(9000000000, 9999999999)}"
if random.random() > 0.8: # 20% анонимных
order.is_anonymous = True
if random.random() > 0.5: # 50% с комментариями
comments = [
"Позвонить за час до доставки",
"Доставить точно в указанное время",
"Не звонить в дверь, только по телефону",
"Упаковать покрасивее",
"Приложить открытку",
]
order.special_instructions = random.choice(comments)
# Сохраняем заказ (чтобы получить ID)
order.save()
# Добавляем товары в заказ
items_count = random.randint(1, 4)
order_products = random.sample(products, min(items_count, len(products)))
items_total = Decimal(0)
for product in order_products:
item = OrderItem()
item.order = order
item.product = product
item.quantity = random.randint(1, 3)
item.price = product.price
item.save()
items_total += item.get_total_price()
# Рассчитываем итоговую сумму
order.total_amount = items_total + order.delivery_cost
# Скидка (20% заказов)
if random.random() > 0.8:
order.discount_amount = Decimal(random.randint(100, 500))
order.total_amount -= order.discount_amount
# Статус оплаты
payment_status_choices = [s[0] for s in payment_statuses]
payment_status_weights = [s[1] for s in payment_statuses]
order.payment_status = random.choices(payment_status_choices, weights=payment_status_weights)[0]
if order.payment_status == 'paid':
order.amount_paid = order.total_amount
order.is_paid = True
elif order.payment_status == 'partial':
order.amount_paid = order.total_amount * Decimal(random.uniform(0.2, 0.8))
order.is_paid = False
else:
order.amount_paid = Decimal(0)
order.is_paid = False
order.save()
created_count += 1
self.stdout.write(f' [OK] Заказ #{order.order_number} на {delivery_date} (товаров: {len(order_products)})')
except Exception as e:
self.stdout.write(self.style.ERROR(f'[ОШИБКА] Заказ {i+1}: {str(e)}'))
self.stdout.write(self.style.SUCCESS(f'\n[ЗАВЕРШЕНО] Успешно создано {created_count} заказов!'))
self.stdout.write(f'Даты доставки: от {today - timedelta(days=15)} до {today + timedelta(days=15)}')
self.stdout.write(self.style.SUCCESS('\n[ВАЖНО] Резервы товаров созданы автоматически через Django сигналы!'))