134 lines
5.6 KiB
Python
134 lines
5.6 KiB
Python
from django.contrib import admin
|
||
from django.utils.html import format_html
|
||
from django.shortcuts import render
|
||
from django_ckeditor_5.widgets import CKEditor5Widget
|
||
from .models import ProductCategory, Configuration, Product, Order
|
||
from programmer.utils.email_notifications import send_multiple_order_notifications, send_multiple_order_notifications_async
|
||
|
||
|
||
@admin.register(ProductCategory)
|
||
class ProductCategoryAdmin(admin.ModelAdmin):
|
||
list_display = ('name', 'slug', 'description')
|
||
prepopulated_fields = {'slug': ('name',)}
|
||
search_fields = ('name',)
|
||
|
||
|
||
@admin.register(Configuration)
|
||
class ConfigurationAdmin(admin.ModelAdmin):
|
||
list_display = ('name', 'slug', 'description')
|
||
prepopulated_fields = {'slug': ('name',)}
|
||
search_fields = ('name',)
|
||
|
||
|
||
@admin.register(Product)
|
||
class ProductAdmin(admin.ModelAdmin):
|
||
|
||
def get_form(self, request, obj=None, **kwargs):
|
||
form = super().get_form(request, obj, **kwargs)
|
||
form.base_fields['content'].widget = CKEditor5Widget(config_name='default')
|
||
return form
|
||
|
||
list_display = ('title', 'category', 'price', 'is_published', 'time_create', 'configurations_list')
|
||
list_filter = ('is_published', 'category', 'configurations', 'time_create')
|
||
search_fields = ('title', 'short_description', 'content')
|
||
prepopulated_fields = {'slug': ('title',)}
|
||
filter_horizontal = ('configurations',)
|
||
date_hierarchy = 'time_create'
|
||
actions = ['make_published', 'make_unpublished']
|
||
|
||
fieldsets = (
|
||
(None, {
|
||
'fields': ('title', 'slug', 'category', 'price', 'is_published')
|
||
}),
|
||
('Описания', {
|
||
'fields': ('short_description', 'content', 'image'),
|
||
'description': 'Краткое – обычный текст для карточки; полное – HTML-редактор для детальной страницы.'
|
||
}),
|
||
('Совместимость', {
|
||
'fields': ('configurations',),
|
||
}),
|
||
('SEO', {
|
||
'fields': ('meta_description',),
|
||
'classes': ('collapse',),
|
||
}),
|
||
)
|
||
|
||
def configurations_list(self, obj):
|
||
return ", ".join(c.name for c in obj.configurations.all())
|
||
configurations_list.short_description = "Конфигурации"
|
||
|
||
def make_published(self, request, queryset):
|
||
queryset.update(is_published=True)
|
||
make_published.short_description = "Опубликовать выбранные продукты"
|
||
|
||
def make_unpublished(self, request, queryset):
|
||
queryset.update(is_published=False)
|
||
make_unpublished.short_description = "Снять с публикации"
|
||
|
||
|
||
@admin.register(Order)
|
||
class OrderAdmin(admin.ModelAdmin):
|
||
list_display = ('id', 'product', 'name', 'phone', 'created_at', 'is_processed', 'notification_sent')
|
||
list_filter = ('is_processed', 'product', 'configuration', 'notification_sent')
|
||
search_fields = ('name', 'phone', 'email')
|
||
list_editable = ('is_processed',)
|
||
readonly_fields = ('created_at',)
|
||
actions = ['resend_order_notification'] # добавляем действие в выпадающий список
|
||
|
||
def notification_badge(self, obj):
|
||
# Если в модели Order добавите поле notification_sent, можно показывать иконку
|
||
# Пока просто заглушка – всегда зелёная галочка (уведомление считается отправленным при создании)
|
||
return format_html('<span style="color:green;">✓</span>')
|
||
notification_badge.short_description = 'Уведомление'
|
||
|
||
def resend_order_notification(self, request, queryset):
|
||
"""
|
||
Переотправляет уведомления для выбранных заказов.
|
||
"""
|
||
# count = send_multiple_order_notifications(queryset)
|
||
count = send_multiple_order_notifications_async(queryset)
|
||
self.message_user(request, f'Уведомления отправлены для {count} заказов.')
|
||
resend_order_notification.short_description = 'Переотправить email уведомления'
|
||
|
||
# Опционально: добавить кастомную кнопку на страницу списка
|
||
def get_urls(self):
|
||
from django.urls import path
|
||
from django.shortcuts import render
|
||
from django.contrib import messages
|
||
|
||
urls = super().get_urls()
|
||
custom_urls = [
|
||
path(
|
||
'order-stats/',
|
||
self.admin_site.admin_view(self.order_stats_view),
|
||
name='order_stats',
|
||
),
|
||
]
|
||
return custom_urls + urls
|
||
|
||
|
||
def notification_badge(self, obj):
|
||
if obj.notification_sent:
|
||
return format_html('<span style="color:green;">✓</span>')
|
||
return format_html('<span style="color:red;">✗</span>')
|
||
|
||
|
||
def order_stats_view(self, request):
|
||
from .models import Order
|
||
from django.utils import timezone
|
||
today = timezone.now().date()
|
||
week_ago = today - timezone.timedelta(days=7)
|
||
|
||
stats = {
|
||
'total': Order.objects.count(),
|
||
'today': Order.objects.filter(created_at__date=today).count(),
|
||
'week': Order.objects.filter(created_at__date__gte=week_ago).count(),
|
||
'unprocessed': Order.objects.filter(is_processed=False).count(),
|
||
}
|
||
context = {
|
||
**self.admin_site.each_context(request),
|
||
'title': 'Статистика заказов',
|
||
'stats': stats,
|
||
}
|
||
return render(request, 'admin/order_stats.html', context)
|
||
|