Files
octopus/myproject/orders/management/commands/create_demo_orders.py
Andrey Smakotin ddbb4f963b Исправлена отображение полей адреса и стили формы заказа
## Основные изменения:

### 1. Исправлена логика выбора режима адреса
- Переместил функцию initAddressModeToggle() из jQuery блока в отдельную функцию
- Теперь инициализация адреса работает независимо от jQuery
- Добавлены подробные логи в консоль для отладки ([ADDRESS MODE] префикс)

### 2. Добавлены CSS классы для управления видимостью
- address-history-mode: display: none !important (по умолчанию скрыт)
- address-new-mode: display: none !important (по умолчанию скрыт)
- .visible класс переводит элементы на display: block !important
- Использование classList.add/remove вместо inline styles

### 3. Исправлены стили полей формы (OrderForm)
- Добавлена явная обработка для Select полей - получают form-select
- Поле "Статус" и другие Select теперь имеют правильные стили Bootstrap
- Разделена логика для RadioSelect, Select и остальных полей

### 4. Улучшена отладка
- Добавлены console.log сообщения на каждом этапе инициализации
- Префикс [ADDRESS MODE] помогает отличить логи системы адреса от других

## Технические детали:

- Address сервис использует метод format_address_for_display() для красивого вывода
- AJAX endpoint get_customer_address_history() загружает адреса клиента
- Три режима адреса: history (из истории), new (новый адрес), empty (без адреса)
- Режим empty выбирается по умолчанию

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 02:49:25 +03:00

207 lines
9.2 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:
# Для доставки выбираем адрес клиента или случайный
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' [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 сигналы!'))