""" Management команда для создания демо-заказов на разные даты """ 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 from customers.models import Customer, Address from shops.models import Shop from products.models import Product class Command(BaseCommand): help = 'Создает 20-30 демо-заказов на разные даты' 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'Начинаем создание демо-заказов в схеме {schema_name}...') # Проверяем наличие необходимых данных 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: # Для доставки выбираем адрес клиента или случайный customer_addresses = list(customer.addresses.all()) if customer_addresses: order.delivery_address = random.choice(customer_addresses) else: 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' Создан заказ #{order.order_number} на {delivery_date}') 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)}')