Implement flexible order status management system
Features: - Created OrderStatus model for managing statuses per tenant - Added system-level statuses: draft, new, confirmed, in_assembly, in_delivery, completed, return, cancelled - Implemented CRUD views for managing order statuses - Created OrderStatusService with status transitions and business logic hooks - Updated Order model to use ForeignKey to OrderStatus - Added is_returned flag for tracking returned orders - Updated filters to work with new OrderStatus model - Created management command for status initialization - Added HTML templates for status list, form, and confirmation - Fixed views.py to use OrderStatus instead of removed STATUS_CHOICES 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -6,8 +6,9 @@ from django.http import JsonResponse
|
||||
from django.views.decorators.http import require_http_methods
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.exceptions import ValidationError
|
||||
from .models import Order, OrderItem, Address
|
||||
from .forms import OrderForm, OrderItemFormSet
|
||||
from django.db import models
|
||||
from .models import Order, OrderItem, Address, OrderStatus
|
||||
from .forms import OrderForm, OrderItemFormSet, OrderStatusForm
|
||||
from .filters import OrderFilter
|
||||
from .services import DraftOrderService
|
||||
from .services.address_service import AddressService
|
||||
@@ -38,7 +39,7 @@ def order_list(request):
|
||||
context = {
|
||||
'filter': order_filter,
|
||||
'page_obj': page_obj,
|
||||
'status_choices': Order.STATUS_CHOICES,
|
||||
'status_choices': OrderStatus.objects.all().order_by('order'),
|
||||
}
|
||||
|
||||
return render(request, 'orders/order_list.html', context)
|
||||
@@ -79,7 +80,8 @@ def order_create(request):
|
||||
|
||||
# Если нажата кнопка "Сохранить как черновик", создаем черновик
|
||||
if 'save_as_draft' in request.POST:
|
||||
order.status = 'draft'
|
||||
from .services.order_status_service import OrderStatusService
|
||||
order.status = OrderStatusService.get_draft_status()
|
||||
order.modified_by = request.user
|
||||
|
||||
order.save()
|
||||
@@ -471,6 +473,121 @@ def get_customer_address_history(request):
|
||||
}, status=500)
|
||||
|
||||
|
||||
# === УПРАВЛЕНИЕ СТАТУСАМИ ЗАКАЗОВ ===
|
||||
|
||||
@login_required
|
||||
def order_status_list(request):
|
||||
"""Список всех статусов заказов"""
|
||||
statuses = OrderStatus.objects.all().order_by('order', 'name')
|
||||
|
||||
# Добавляем информацию о количестве заказов для каждого статуса
|
||||
for status in statuses:
|
||||
status.orders_count = Order.objects.filter(status=status).count()
|
||||
|
||||
context = {
|
||||
'statuses': statuses,
|
||||
'title': 'Статусы заказов'
|
||||
}
|
||||
|
||||
return render(request, 'orders/status_list.html', context)
|
||||
|
||||
|
||||
@login_required
|
||||
def order_status_create(request):
|
||||
"""Создание нового статуса"""
|
||||
if request.method == 'POST':
|
||||
form = OrderStatusForm(request.POST)
|
||||
|
||||
if form.is_valid():
|
||||
status = form.save(commit=False)
|
||||
status.created_by = request.user
|
||||
status.updated_by = request.user
|
||||
|
||||
# Если не указан порядок - делаем его последним
|
||||
if not status.order:
|
||||
max_order = OrderStatus.objects.aggregate(models.Max('order'))['order__max'] or 0
|
||||
status.order = max_order + 10
|
||||
|
||||
status.save()
|
||||
messages.success(request, f'Статус "{status.name}" успешно создан')
|
||||
return redirect('orders:status_list')
|
||||
else:
|
||||
form = OrderStatusForm()
|
||||
|
||||
context = {
|
||||
'form': form,
|
||||
'title': 'Создать новый статус',
|
||||
'button_text': 'Создать'
|
||||
}
|
||||
|
||||
return render(request, 'orders/status_form.html', context)
|
||||
|
||||
|
||||
@login_required
|
||||
def order_status_update(request, pk):
|
||||
"""Редактирование статуса"""
|
||||
status = get_object_or_404(OrderStatus, pk=pk)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = OrderStatusForm(request.POST, instance=status)
|
||||
|
||||
if form.is_valid():
|
||||
status = form.save(commit=False)
|
||||
status.updated_by = request.user
|
||||
status.save()
|
||||
messages.success(request, f'Статус "{status.name}" успешно обновлен')
|
||||
return redirect('orders:status_list')
|
||||
else:
|
||||
form = OrderStatusForm(instance=status)
|
||||
|
||||
context = {
|
||||
'form': form,
|
||||
'status': status,
|
||||
'title': f'Редактировать статус: {status.name}',
|
||||
'button_text': 'Сохранить',
|
||||
'is_system': status.is_system
|
||||
}
|
||||
|
||||
return render(request, 'orders/status_form.html', context)
|
||||
|
||||
|
||||
@login_required
|
||||
def order_status_delete(request, pk):
|
||||
"""Удаление статуса"""
|
||||
status = get_object_or_404(OrderStatus, pk=pk)
|
||||
|
||||
if status.is_system:
|
||||
messages.error(request, f'Нельзя удалить системный статус "{status.name}"')
|
||||
return redirect('orders:status_list')
|
||||
|
||||
if request.method == 'POST':
|
||||
# Проверяем, что статус не используется в заказах
|
||||
orders_count = Order.objects.filter(status=status).count()
|
||||
|
||||
if orders_count > 0:
|
||||
messages.error(
|
||||
request,
|
||||
f'Невозможно удалить статус. Есть {orders_count} заказов с этим статусом.'
|
||||
)
|
||||
return redirect('orders:status_list')
|
||||
|
||||
status_name = status.name
|
||||
status.delete()
|
||||
messages.success(request, f'Статус "{status_name}" успешно удален')
|
||||
return redirect('orders:status_list')
|
||||
|
||||
# Информация для подтверждения удаления
|
||||
orders_count = Order.objects.filter(status=status).count()
|
||||
|
||||
context = {
|
||||
'status': status,
|
||||
'orders_count': orders_count,
|
||||
'title': 'Удалить статус'
|
||||
}
|
||||
|
||||
return render(request, 'orders/status_confirm_delete.html', context)
|
||||
|
||||
|
||||
# === ВРЕМЕННЫЕ КОМПЛЕКТЫ ===
|
||||
# УДАЛЕНО: Логика создания временных комплектов перенесена в products.services.kit_service
|
||||
# Используйте API endpoint: products:api-temporary-kit-create
|
||||
|
||||
Reference in New Issue
Block a user