feat: Добавлена функциональность управления заказами и улучшен поиск товаров
Заказы: - Добавлены миграции для исторических записей с полями оплаты и получателя - Расширен admin для заказов с инлайнами товаров/комплектов - Реализованы представления списка, создания, редактирования и удаления заказов - Добавлен шаблон подтверждения удаления заказа - Настроены URL-маршруты для работы с заказами Клиенты: - Добавлена миграция с новыми полями адресов и подтверждений - Обновлена модель клиентов с дополнительными полями - Улучшен admin для работы с клиентами Товары: - Значительно улучшен API поиска товаров с поддержкой фильтрации - Добавлен Select2 виджет для динамического поиска товаров - Создан статический JS файл для интеграции Select2 - Оптимизирована обработка запросов и ответов API Прочее: - Добавлены новые настройки в settings.py - Обновлена навигация в navbar.html - Обновлены URL-маршруты проекта 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,155 @@
|
||||
from django.shortcuts import render
|
||||
# -*- coding: utf-8 -*-
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.contrib import messages
|
||||
from django.core.paginator import Paginator
|
||||
from django.db.models import Q
|
||||
from .models import Order, OrderItem
|
||||
from .forms import OrderForm, OrderItemFormSet
|
||||
|
||||
# Create your views here.
|
||||
|
||||
def order_list(request):
|
||||
"""Список всех заказов с фильтрацией и поиском"""
|
||||
orders = Order.objects.select_related('customer', 'delivery_address', 'pickup_shop').all()
|
||||
|
||||
# Поиск
|
||||
search_query = request.GET.get('search', '')
|
||||
if search_query:
|
||||
orders = orders.filter(
|
||||
Q(order_number__icontains=search_query) |
|
||||
Q(customer__name__icontains=search_query) |
|
||||
Q(customer__phone__icontains=search_query) |
|
||||
Q(customer__email__icontains=search_query)
|
||||
)
|
||||
|
||||
# Фильтр по статусу
|
||||
status_filter = request.GET.get('status', '')
|
||||
if status_filter:
|
||||
orders = orders.filter(status=status_filter)
|
||||
|
||||
# Фильтр по типу доставки
|
||||
delivery_filter = request.GET.get('delivery_type', '')
|
||||
if delivery_filter == 'delivery':
|
||||
orders = orders.filter(is_delivery=True)
|
||||
elif delivery_filter == 'pickup':
|
||||
orders = orders.filter(is_delivery=False)
|
||||
|
||||
# Сортировка
|
||||
orders = orders.order_by('-created_at')
|
||||
|
||||
# Пагинация
|
||||
paginator = Paginator(orders, 25)
|
||||
page_number = request.GET.get('page')
|
||||
page_obj = paginator.get_page(page_number)
|
||||
|
||||
context = {
|
||||
'page_obj': page_obj,
|
||||
'search_query': search_query,
|
||||
'status_filter': status_filter,
|
||||
'delivery_filter': delivery_filter,
|
||||
'status_choices': Order.STATUS_CHOICES,
|
||||
}
|
||||
|
||||
return render(request, 'orders/order_list.html', context)
|
||||
|
||||
|
||||
def order_detail(request, pk):
|
||||
"""Детальная информация о заказе"""
|
||||
order = get_object_or_404(
|
||||
Order.objects.select_related('customer', 'delivery_address', 'pickup_shop', 'modified_by')
|
||||
.prefetch_related('items__product', 'items__product_kit', 'payments__created_by'),
|
||||
pk=pk
|
||||
)
|
||||
|
||||
context = {
|
||||
'order': order,
|
||||
}
|
||||
|
||||
return render(request, 'orders/order_detail.html', context)
|
||||
|
||||
|
||||
def order_create(request):
|
||||
"""Создание нового заказа"""
|
||||
if request.method == 'POST':
|
||||
form = OrderForm(request.POST)
|
||||
formset = OrderItemFormSet(request.POST)
|
||||
|
||||
if form.is_valid() and formset.is_valid():
|
||||
order = form.save(commit=False)
|
||||
order.save()
|
||||
|
||||
# Сохраняем позиции заказа
|
||||
formset.instance = order
|
||||
formset.save()
|
||||
|
||||
# Пересчитываем итоговую сумму
|
||||
order.calculate_total()
|
||||
order.save()
|
||||
|
||||
messages.success(request, f'Заказ #{order.order_number} успешно создан!')
|
||||
return redirect('orders:order-detail', pk=order.pk)
|
||||
else:
|
||||
messages.error(request, 'Пожалуйста, исправьте ошибки в форме.')
|
||||
else:
|
||||
form = OrderForm()
|
||||
formset = OrderItemFormSet()
|
||||
|
||||
context = {
|
||||
'form': form,
|
||||
'formset': formset,
|
||||
'title': 'Создание заказа',
|
||||
'button_text': 'Создать заказ',
|
||||
}
|
||||
|
||||
return render(request, 'orders/order_form.html', context)
|
||||
|
||||
|
||||
def order_update(request, pk):
|
||||
"""Редактирование заказа"""
|
||||
order = get_object_or_404(Order, pk=pk)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = OrderForm(request.POST, instance=order)
|
||||
formset = OrderItemFormSet(request.POST, instance=order)
|
||||
|
||||
if form.is_valid() and formset.is_valid():
|
||||
order = form.save()
|
||||
formset.save()
|
||||
|
||||
# Пересчитываем итоговую сумму
|
||||
order.calculate_total()
|
||||
order.save()
|
||||
|
||||
messages.success(request, f'Заказ #{order.order_number} успешно обновлен!')
|
||||
return redirect('orders:order-detail', pk=order.pk)
|
||||
else:
|
||||
messages.error(request, 'Пожалуйста, исправьте ошибки в форме.')
|
||||
else:
|
||||
form = OrderForm(instance=order)
|
||||
formset = OrderItemFormSet(instance=order)
|
||||
|
||||
context = {
|
||||
'form': form,
|
||||
'formset': formset,
|
||||
'order': order,
|
||||
'title': f'Редактирование заказа #{order.order_number}',
|
||||
'button_text': 'Сохранить изменения',
|
||||
}
|
||||
|
||||
return render(request, 'orders/order_form.html', context)
|
||||
|
||||
|
||||
def order_delete(request, pk):
|
||||
"""Удаление заказа с подтверждением"""
|
||||
order = get_object_or_404(Order, pk=pk)
|
||||
|
||||
if request.method == 'POST':
|
||||
order_number = order.order_number
|
||||
order.delete()
|
||||
messages.success(request, f'Заказ #{order_number} успешно удален.')
|
||||
return redirect('orders:order-list')
|
||||
|
||||
context = {
|
||||
'order': order,
|
||||
}
|
||||
|
||||
return render(request, 'orders/order_confirm_delete.html', context)
|
||||
|
||||
Reference in New Issue
Block a user