diff --git a/shop/admin.py b/shop/admin.py index 58dd0ee..0eaf59d 100644 --- a/shop/admin.py +++ b/shop/admin.py @@ -1,10 +1,14 @@ from django.contrib import admin -from django.shortcuts import render -from .models import Product, Color, Size, Order, OrderItem, GuestUser, Coupon, CouponUsage, OrderStatus, ShippingAddress +from django.shortcuts import render, redirect from django.utils.html import format_html from django.urls import path -from django.contrib import admin -from django.shortcuts import redirect +from django.http import HttpResponseRedirect +from django import forms + +from .models import ( + Product, Color, Size, Order, OrderItem, GuestUser, Coupon, CouponUsage, + OrderStatus, ShippingAddress +) @admin.register(Product) class ProductAdmin(admin.ModelAdmin): @@ -45,18 +49,24 @@ class ShippingAddressAdmin(admin.ModelAdmin): list_display = ('street_address', 'city', 'postal_code', 'country') search_fields = ('street_address', 'city', 'postal_code', 'country') +class ChangeOrderStatusForm(forms.Form): + _selected_action = forms.CharField(widget=forms.MultipleHiddenInput) + status = forms.ChoiceField(choices=OrderStatus.choices, label="New Status") + @admin.register(Order) class OrderAdmin(admin.ModelAdmin): list_display = ('id', 'get_email', 'date_ordered', 'status', 'total_price', 'get_shipping_address') inlines = [OrderItemInline] list_filter = ('status', 'payment_status') readonly_fields = ('shipping_address_details',) + actions = ['change_order_status'] def get_email(self, obj): if obj.guest_user: return obj.guest_user.email else: return obj.user.email + get_email.short_description = 'Email' def get_shipping_address(self, obj): if obj.shipping_address: @@ -198,6 +208,38 @@ class OrderAdmin(admin.ModelAdmin): except Exception as e: self.message_user(request, f"Error cancelling order: {str(e)}", level='ERROR') return redirect('admin:shop_order_changelist') + + def change_order_status(self, request, queryset): + """Admin action to change the status of selected orders""" + form = None + + if 'apply' in request.POST: + form = ChangeOrderStatusForm(request.POST) + + if form.is_valid(): + status = form.cleaned_data['status'] + count = 0 + + for order in queryset: + order.status = status + order.save() + count += 1 + + self.message_user(request, f"{count} orders have been updated to status '{OrderStatus(status).label}'.") + return HttpResponseRedirect(request.get_full_path()) + + if not form: + form = ChangeOrderStatusForm(initial={'_selected_action': request.POST.getlist('_selected_action')}) + + context = { + 'title': 'Change Order Status', + 'orders': queryset, + 'form': form, + 'action': 'change_order_status' + } + return render(request, 'admin/shop/order/change_status.html', context) + + change_order_status.short_description = "Change status for selected orders" class GuestUserOrderInline(admin.TabularInline): model = Order @@ -240,4 +282,4 @@ 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',) + readonly_fields = ('used_at',) \ No newline at end of file diff --git a/shop/signals.py b/shop/signals.py index 93c05d7..3466662 100644 --- a/shop/signals.py +++ b/shop/signals.py @@ -238,7 +238,7 @@ Montant payé: {final_price}€""" } # Order status update email - elif status in [OrderStatus.SHIPPED, OrderStatus.DELIVERED, OrderStatus.CANCELED, OrderStatus.PREPARED, OrderStatus.REFUNDED]: + elif status in [OrderStatus.SHIPPED, OrderStatus.DELIVERED, OrderStatus.CANCELED, OrderStatus.PREPARED, OrderStatus.REFUNDED, OrderStatus.READY]: status_message = { OrderStatus.PREPARED: "Votre commande est en cours de préparation.", OrderStatus.READY: "Votre commande est prête.", diff --git a/shop/templates/admin/shop/order/change_status.html b/shop/templates/admin/shop/order/change_status.html new file mode 100644 index 0000000..8a0cff5 --- /dev/null +++ b/shop/templates/admin/shop/order/change_status.html @@ -0,0 +1,32 @@ +{% extends "admin/base_site.html" %} +{% load i18n l10n admin_urls %} + +{% block content %} +
+

{{ title }}

+
+

Change status for the following {{ orders|length }} orders:

+ +
+ +
+ {% csrf_token %} + + + {{ form.as_p }} + + {% for obj in orders %} + + {% endfor %} + +
+ + Cancel +
+
+
+{% endblock %} \ No newline at end of file