from django.contrib import admin 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) class ProductAdmin(admin.ModelAdmin): list_display = ("title", "ordering_value", "price", "cut") @admin.register(Color) class ColorAdmin(admin.ModelAdmin): list_display = ("color_preview", "name", "ordering", "colorHex", "secondary_hex_color") list_editable = ("ordering",) ordering = ["ordering"] search_fields = ["name"] list_per_page = 20 def color_preview(self, obj): if obj.secondary_hex_color: return format_html( '
', obj.colorHex, obj.secondary_hex_color ) return format_html( '
', obj.colorHex ) @admin.register(Size) class SizeAdmin(admin.ModelAdmin): list_display = ("name",) class OrderItemInline(admin.TabularInline): model = OrderItem extra = 0 readonly_fields = ('product', 'quantity', 'color', 'size', 'price') @admin.register(Order) 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 extra = 0 readonly_fields = ('date_ordered', 'total_price') can_delete = False show_change_link = True exclude = ('user',) # Exclude the user field from the inline display @admin.register(GuestUser) class GuestUserAdmin(admin.ModelAdmin): list_display = ('email', 'phone') inlines = [GuestUserOrderInline] @admin.register(Coupon) class CouponAdmin(admin.ModelAdmin): list_display = ('code', 'discount_amount', 'discount_percent', 'is_active', 'valid_from', 'valid_to', 'current_uses', 'max_uses') list_filter = ('is_active', 'valid_from', 'valid_to') search_fields = ('code', 'description') readonly_fields = ('current_uses', 'created_at', 'stripe_coupon_id') fieldsets = ( ('Basic Information', { 'fields': ('code', 'description', 'is_active') }), ('Discount', { 'fields': ('discount_amount', 'discount_percent') }), ('Validity', { 'fields': ('valid_from', 'valid_to', 'max_uses', 'current_uses') }), ('Stripe Information', { 'fields': ('stripe_coupon_id',), 'classes': ('collapse',) }), ) @admin.register(CouponUsage) class CouponUsageAdmin(admin.ModelAdmin): list_display = ('coupon', 'user', 'guest_email', 'order', 'used_at') list_filter = ('used_at',) search_fields = ('coupon__code', 'user__username', 'user__email', 'guest_email') readonly_fields = ('used_at',)