add order recap

timetoconfirm
Raz 7 months ago
parent aa630d1348
commit 1f64fd0a7d
  1. 64
      shop/admin.py
  2. 18
      shop/templates/admin/shop/order/change_list.html
  3. 103
      shop/templates/admin/shop/order/preparation_view.html

@ -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

@ -0,0 +1,18 @@
{% extends "admin/change_list.html" %}
{% block object-tools %}
<ul class="object-tools">
<li>
<a href="?show_preparation=1" class="viewlink">
Orders to Prepare ({{ paid_orders_count }})
</a>
</li>
{% if has_add_permission %}
<li>
<a href="{% url 'admin:shop_order_add' %}" class="addlink">
Add Order
</a>
</li>
{% endif %}
</ul>
{% endblock %}

@ -0,0 +1,103 @@
{% extends "admin/base_site.html" %}
{% block content %}
<div id="content-main">
<p>Total orders with status PAID: {{ total_orders }}</p>
<p>Total items to prepare: {{ total_items }}</p>
<button onclick="window.print()" style="margin-bottom: 20px">Print This Page</button>
<a href="?" class="button" style="margin-left: 10px">Back to Orders</a>
<h2>Items Summary</h2>
<table style="width: 100%; border-collapse: collapse;">
<thead>
<tr>
<th style="text-align: left; padding: 8px; border-bottom: 1px solid #ddd;">Product</th>
<th style="text-align: left; padding: 8px; border-bottom: 1px solid #ddd;">Color</th>
<th style="text-align: left; padding: 8px; border-bottom: 1px solid #ddd;">Size</th>
<th style="text-align: left; padding: 8px; border-bottom: 1px solid #ddd;">Quantity</th>
<th style="text-align: left; padding: 8px; border-bottom: 1px solid #ddd;">Orders</th>
</tr>
</thead>
<tbody>
{% for item in items %}
<tr>
<td style="padding: 8px; border-bottom: 1px solid #ddd;">{{ item.product.title }}</td>
<td style="padding: 8px; border-bottom: 1px solid #ddd;">
{% if item.color %}
<span style="display: inline-block; width: 15px; height: 15px; border-radius: 50%; background-color: {{ item.color.colorHex }}; margin-right: 5px;"></span>
{{ item.color.name }}
{% else %}
-
{% endif %}
</td>
<td style="padding: 8px; border-bottom: 1px solid #ddd;">{{ item.size.name|default:"-" }}</td>
<td style="padding: 8px; border-bottom: 1px solid #ddd; font-weight: bold;">{{ item.quantity }}</td>
<td style="padding: 8px; border-bottom: 1px solid #ddd;">
{% for order_id in item.orders %}
<a href="../{{ order_id }}/change/">Order #{{ order_id }}</a>{% if not forloop.last %}, {% endif %}
{% endfor %}
</td>
</tr>
{% empty %}
<tr>
<td colspan="5" style="padding: 8px; text-align: center;">No items to prepare</td>
</tr>
{% endfor %}
</tbody>
</table>
<h2 style="margin-top: 30px;">Order Details</h2>
<table style="width: 100%; border-collapse: collapse;">
<thead>
<tr>
<th style="text-align: left; padding: 8px; border-bottom: 1px solid #ddd;">Order #</th>
<th style="text-align: left; padding: 8px; border-bottom: 1px solid #ddd;">Date</th>
<th style="text-align: left; padding: 8px; border-bottom: 1px solid #ddd;">Customer</th>
<th style="text-align: left; padding: 8px; border-bottom: 1px solid #ddd;">Items</th>
</tr>
</thead>
<tbody>
{% for order in orders %}
<tr>
<td style="padding: 8px; border-bottom: 1px solid #ddd;"><a href="../{{ order.id }}/change/">Order #{{ order.id }}</a></td>
<td style="padding: 8px; border-bottom: 1px solid #ddd;">{{ order.date_ordered|date:"Y-m-d H:i" }}</td>
<td style="padding: 8px; border-bottom: 1px solid #ddd;">
{% if order.user %}
{{ order.user.email }}
{% elif order.guest_user %}
{{ order.guest_user.email }} (Guest)
{% else %}
Unknown
{% endif %}
</td>
<td style="padding: 8px; border-bottom: 1px solid #ddd;">
{% 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 %}
<br>
{% endfor %}
</td>
</tr>
{% empty %}
<tr>
<td colspan="4" style="padding: 8px; text-align: center;">No orders found</td>
</tr>
{% endfor %}
</tbody>
</table>
<style>
@media print {
button, .button, #header, .breadcrumbs {
display: none !important;
}
body {
padding: 0;
margin: 0;
}
}
</style>
</div>
{% endblock %}
Loading…
Cancel
Save