Добавлены новые статусы заказов: Частично собран и Полностью собран
- Добавлены системные статусы partially_assembled и fully_assembled в order_status_service.py - Создана management команда update_order_statuses для обновления статусов у всех тенантов - Новые статусы интегрируются в существующую логику резервирования и списания товара - Статусы располагаются между 'В сборке' и 'В доставке' в естественном порядке процесса
This commit is contained in:
112
myproject/orders/management/commands/update_order_statuses.py
Normal file
112
myproject/orders/management/commands/update_order_statuses.py
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Management команда для обновления системных статусов заказов у всех тенантов.
|
||||||
|
|
||||||
|
Использование:
|
||||||
|
# Обновить статусы у всех тенантов
|
||||||
|
python manage.py update_order_statuses --all
|
||||||
|
|
||||||
|
# Обновить статусы у конкретного тенанта
|
||||||
|
python manage.py update_order_statuses --schema=anatol
|
||||||
|
"""
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from django_tenants.utils import get_tenant_model, schema_context
|
||||||
|
from orders.services.order_status_service import OrderStatusService
|
||||||
|
from orders.models import OrderStatus
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = 'Обновление системных статусов заказов (добавляет новые статусы если их нет)'
|
||||||
|
|
||||||
|
def add_arguments(self, parser):
|
||||||
|
parser.add_argument(
|
||||||
|
'--all',
|
||||||
|
action='store_true',
|
||||||
|
help='Обновить статусы у всех тенантов'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--schema',
|
||||||
|
type=str,
|
||||||
|
help='Имя схемы конкретного тенанта'
|
||||||
|
)
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
update_all = options.get('all', False)
|
||||||
|
schema_name = options.get('schema')
|
||||||
|
|
||||||
|
if not update_all and not schema_name:
|
||||||
|
self.stdout.write(
|
||||||
|
self.style.ERROR('Укажите либо --all для всех тенантов, либо --schema=<имя> для конкретного')
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
Tenant = get_tenant_model()
|
||||||
|
|
||||||
|
if update_all:
|
||||||
|
# Обновляем у всех тенантов (кроме public)
|
||||||
|
tenants = Tenant.objects.exclude(schema_name='public')
|
||||||
|
self.stdout.write(
|
||||||
|
self.style.SUCCESS(f'\n=== Обновление статусов у всех тенантов ({tenants.count()}) ===\n')
|
||||||
|
)
|
||||||
|
|
||||||
|
for tenant in tenants:
|
||||||
|
self._update_tenant_statuses(tenant)
|
||||||
|
else:
|
||||||
|
# Обновляем у конкретного тенанта
|
||||||
|
try:
|
||||||
|
tenant = Tenant.objects.get(schema_name=schema_name)
|
||||||
|
self.stdout.write(
|
||||||
|
self.style.SUCCESS(f'\n=== Обновление статусов тенанта: {tenant.name} ===\n')
|
||||||
|
)
|
||||||
|
self._update_tenant_statuses(tenant)
|
||||||
|
except Tenant.DoesNotExist:
|
||||||
|
self.stdout.write(
|
||||||
|
self.style.ERROR(f'\nОШИБКА: Тенант со схемой "{schema_name}" не найден\n')
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
self.stdout.write(self.style.SUCCESS('\n✓ Обновление завершено!\n'))
|
||||||
|
|
||||||
|
def _update_tenant_statuses(self, tenant):
|
||||||
|
"""Обновляет статусы для конкретного тенанта"""
|
||||||
|
self.stdout.write(f'\nТенант: {tenant.name} ({tenant.schema_name})')
|
||||||
|
self.stdout.write('-' * 70)
|
||||||
|
|
||||||
|
with schema_context(tenant.schema_name):
|
||||||
|
try:
|
||||||
|
# Получаем количество статусов до
|
||||||
|
before_count = OrderStatus.objects.filter(is_system=True).count()
|
||||||
|
|
||||||
|
# Создаем/обновляем системные статусы
|
||||||
|
OrderStatusService.create_default_statuses()
|
||||||
|
|
||||||
|
# Получаем количество статусов после
|
||||||
|
after_count = OrderStatus.objects.filter(is_system=True).count()
|
||||||
|
new_count = after_count - before_count
|
||||||
|
|
||||||
|
if new_count > 0:
|
||||||
|
self.stdout.write(
|
||||||
|
self.style.SUCCESS(f' ✓ Добавлено новых статусов: {new_count}')
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.stdout.write(
|
||||||
|
self.style.WARNING(f' • Все статусы уже существуют ({after_count})')
|
||||||
|
)
|
||||||
|
|
||||||
|
# Выводим список всех системных статусов
|
||||||
|
statuses = OrderStatus.objects.filter(is_system=True).order_by('order')
|
||||||
|
self.stdout.write(f'\n Системные статусы ({statuses.count()}):')
|
||||||
|
for status in statuses:
|
||||||
|
end_type = ''
|
||||||
|
if status.is_positive_end:
|
||||||
|
end_type = ' [Успешный]'
|
||||||
|
elif status.is_negative_end:
|
||||||
|
end_type = ' [Отрицательный]'
|
||||||
|
self.stdout.write(
|
||||||
|
f' {status.order:>2}. {status.name:<25} ({status.code:<20}){end_type}'
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.stdout.write(
|
||||||
|
self.style.ERROR(f' ✗ Ошибка при обновлении статусов: {e}')
|
||||||
|
)
|
||||||
@@ -93,6 +93,24 @@ class OrderStatusService:
|
|||||||
'color': '#FF9800',
|
'color': '#FF9800',
|
||||||
'description': 'Заказ находится в процессе сборки/подготовки'
|
'description': 'Заказ находится в процессе сборки/подготовки'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'code': 'partially_assembled',
|
||||||
|
'name': 'Частично собран',
|
||||||
|
'label': 'Частично собран',
|
||||||
|
'is_system': True,
|
||||||
|
'order': 35,
|
||||||
|
'color': '#FFC107',
|
||||||
|
'description': 'Заказ частично собран, некоторые позиции готовы'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'code': 'fully_assembled',
|
||||||
|
'name': 'Полностью собран',
|
||||||
|
'label': 'Полностью собран',
|
||||||
|
'is_system': True,
|
||||||
|
'order': 38,
|
||||||
|
'color': '#8BC34A',
|
||||||
|
'description': 'Заказ полностью собран и готов к отгрузке/доставке'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'code': 'in_delivery',
|
'code': 'in_delivery',
|
||||||
'name': 'В доставке',
|
'name': 'В доставке',
|
||||||
|
|||||||
Reference in New Issue
Block a user