From 1f64fd0a7d600194b596f5cadf48fa0b8d56d2ab Mon Sep 17 00:00:00 2001 From: Raz Date: Mon, 7 Apr 2025 14:12:31 +0200 Subject: [PATCH] add order recap --- shop/admin.py | 64 ++++++++++- .../admin/shop/order/change_list.html | 18 +++ .../admin/shop/order/preparation_view.html | 103 ++++++++++++++++++ 3 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 shop/templates/admin/shop/order/change_list.html create mode 100644 shop/templates/admin/shop/order/preparation_view.html diff --git a/shop/admin.py b/shop/admin.py index 62fa1b3..72d69c6 100644 --- a/shop/admin.py +++ b/shop/admin.py @@ -1,5 +1,6 @@ from django.contrib import admin -from .models import Product, Color, Size, Order, OrderItem, GuestUser, Coupon, CouponUsage +from django.shortcuts import render +from .models import Product, Color, Size, Order, OrderItem, GuestUser, Coupon, CouponUsage, OrderStatus from django.utils.html import format_html @admin.register(Product) @@ -40,6 +41,67 @@ class OrderItemInline(admin.TabularInline): class OrderAdmin(admin.ModelAdmin): list_display = ('id', 'date_ordered', 'status', 'total_price') inlines = [OrderItemInline] + list_filter = ('status', 'payment_status') + + def changelist_view(self, request, extra_context=None): + # If 'show_preparation' parameter is in the request, show the preparation view + if 'show_preparation' in request.GET: + return self.preparation_view(request) + + # Otherwise show the normal change list + extra_context = extra_context or {} + paid_orders_count = Order.objects.filter(status=OrderStatus.PAID).count() + extra_context['paid_orders_count'] = paid_orders_count + return super().changelist_view(request, extra_context=extra_context) + + def preparation_view(self, request): + """View for items that need to be prepared""" + # Get paid orders + orders = Order.objects.filter(status=OrderStatus.PAID).order_by('-date_ordered') + + # Group items by product, color, size + items_by_variant = {} + all_items = OrderItem.objects.filter(order__status=OrderStatus.PAID) + + for item in all_items: + # Create a key for grouping items + key = ( + str(item.product.id), + str(item.color.id) if item.color else 'none', + str(item.size.id) if item.size else 'none' + ) + + if key not in items_by_variant: + items_by_variant[key] = { + 'product': item.product, + 'color': item.color, + 'size': item.size, + 'quantity': 0, + 'orders': set() + } + + items_by_variant[key]['quantity'] += item.quantity + items_by_variant[key]['orders'].add(item.order.id) + + # Convert to list and sort + items_list = list(items_by_variant.values()) + items_list.sort(key=lambda x: x['product'].title) + + context = { + 'title': 'Orders to Prepare', + 'app_label': 'shop', + 'opts': Order._meta, + 'orders': orders, + 'items': items_list, + 'total_orders': orders.count(), + 'total_items': sum(i['quantity'] for i in items_list) + } + + return render( + request, + 'admin/shop/order/preparation_view.html', + context + ) class GuestUserOrderInline(admin.TabularInline): model = Order diff --git a/shop/templates/admin/shop/order/change_list.html b/shop/templates/admin/shop/order/change_list.html new file mode 100644 index 0000000..e3e7fdc --- /dev/null +++ b/shop/templates/admin/shop/order/change_list.html @@ -0,0 +1,18 @@ +{% extends "admin/change_list.html" %} + +{% block object-tools %} + +{% endblock %} diff --git a/shop/templates/admin/shop/order/preparation_view.html b/shop/templates/admin/shop/order/preparation_view.html new file mode 100644 index 0000000..63213a5 --- /dev/null +++ b/shop/templates/admin/shop/order/preparation_view.html @@ -0,0 +1,103 @@ +{% extends "admin/base_site.html" %} + +{% block content %} +
+

Total orders with status PAID: {{ total_orders }}

+

Total items to prepare: {{ total_items }}

+ + + Back to Orders + +

Items Summary

+ + + + + + + + + + + + {% for item in items %} + + + + + + + + {% empty %} + + + + {% endfor %} + +
ProductColorSizeQuantityOrders
{{ item.product.title }} + {% if item.color %} + + {{ item.color.name }} + {% else %} + - + {% endif %} + {{ item.size.name|default:"-" }}{{ item.quantity }} + {% for order_id in item.orders %} + Order #{{ order_id }}{% if not forloop.last %}, {% endif %} + {% endfor %} +
No items to prepare
+ +

Order Details

+ + + + + + + + + + + {% for order in orders %} + + + + + + + {% empty %} + + + + {% endfor %} + +
Order #DateCustomerItems
Order #{{ order.id }}{{ order.date_ordered|date:"Y-m-d H:i" }} + {% if order.user %} + {{ order.user.email }} + {% elif order.guest_user %} + {{ order.guest_user.email }} (Guest) + {% else %} + Unknown + {% endif %} + + {% for item in order.items.all %} + {{ item.quantity }}x {{ item.product.title }} + {% if item.color %} ({{ item.color.name }}){% endif %} + {% if item.size %} [{{ item.size.name }}]{% endif %} +
+ {% endfor %} +
No orders found
+ + +
+{% endblock %}