diff --git a/backend/product/admin.py b/backend/product/admin.py index b8720fd..b55a937 100644 --- a/backend/product/admin.py +++ b/backend/product/admin.py @@ -11,8 +11,9 @@ from django.contrib.postgres.fields import ArrayField from unfold.widgets import UnfoldAdminColorInputWidget from unfold.decorators import action, display from utils.admin import ModelAdmin -from django.shortcuts import redirect +from django.shortcuts import redirect, render from .permissions import ProductDetailCategoryPermission, ProductAdminPermission, ProductVariantAdminPermission, ProductVariantInlineAdminPermission, InPackItemsAdminPermission, AttributeTypeAdminPermission, AttributeValueAdminPermission +from django import forms @admin.register(ProductDetailCategory) class ProductDetailCategoryAdmin(ProductDetailCategoryPermission, ModelAdmin, ImportExportModelAdmin): @@ -240,6 +241,18 @@ class ProductVariantInLine(ProductVariantInlineAdminPermission, StackedInline): return super().formfield_for_dbfield(db_field, request, **kwargs) from unfold.contrib.filters.admin import RelatedDropdownFilter + + +class BulkSubCategoryForm(forms.Form): + """فرم برای انتخاب زیر دستهبندی برای محصولات""" + subcategory = forms.ModelChoiceField( + queryset=SubCategoryModel.objects.all(), + required=True, + label='زیر دستهبندی', + help_text='زیر دستهبندی جدید را برای محصولات انتخاب شده انتخاب کنید' + ) + + @admin.register(ProductVariant) class ProductVariantAdmin(ProductVariantAdminPermission, ModelAdmin, ImportExportModelAdmin): form = ProductVariantAdminForm @@ -270,6 +283,7 @@ class ProductModelAdmin(ProductAdminPermission, ModelAdmin, ImportExportModelAdm autocomplete_fields = ['related_products', 'shop'] # compressed_fields = True warn_unsaved_form = True + list_per_page = 2 actions_list = ['redirect_to_learn', 'update_products_price'] list_display = ['display_image', 'shop__shop_name','display_price', 'view', 'show', 'rating', 'category', 'created_at'] fieldsets = ( @@ -319,6 +333,46 @@ class ProductModelAdmin(ProductAdminPermission, ModelAdmin, ImportExportModelAdm messages.success(request, f"قیمت {ProductVariant.objects.all().count()} تنوع محصول اپدیت شد") return redirect("admin:product_productmodel_changelist") + def bulk_update_subcategory_action(self, request, queryset): + """اکشن برای تغییر دستهبندی چند محصول همزمان""" + + # اگر فرم ارسال شده است + if 'apply' in request.POST: + form = BulkSubCategoryForm(request.POST) + + if form.is_valid(): + subcategory = form.cleaned_data['subcategory'] + count = queryset.count() + + # بهروزرسانی تمام محصولات انتخاب شده + queryset.update(category=subcategory) + + messages.success( + request, + f'دستهبندی {count} محصول به "{subcategory.name}" تغییر یافت.' + ) + return redirect('admin:product_productmodel_changelist') + else: + form = BulkSubCategoryForm() + + # نمایش صفحه تأیید + context = { + 'form': form, + 'products': queryset, + 'selected_ids': list(queryset.values_list('pk', flat=True)), + 'action_name': 'bulk_update_subcategory_action', + 'title': 'تغییر دستهبندی محصولات', + } + + return render( + request, + 'admin/product/bulk_subcategory_form.html', + context + ) + + bulk_update_subcategory_action.short_description = "تغییر دستهبندی محصولات انتخاب شده" + actions = ['bulk_update_subcategory_action'] + # @display( # description=("نمایش در صفحه ی اصلی"), diff --git a/backend/product/models.py b/backend/product/models.py index 0ad8a7a..b3c704d 100644 --- a/backend/product/models.py +++ b/backend/product/models.py @@ -385,7 +385,7 @@ class ProductVariant(DirtyFieldsMixin, models.Model): price_in_dollor = models.DecimalField( max_digits=15, decimal_places=8, blank=True, null=True, verbose_name='قیمت به دلار', help_text='قیمت محصول به دلار (محاسبه خودکار)') - discount = models.SmallIntegerField(default=0, verbose_name='درصد تخفیف', help_text='این درصد از قیمت نهایی محصول کسر میگردد) + discount = models.SmallIntegerField(default=0, verbose_name='درصد تخفیف', help_text='این درصد از قیمت نهایی محصول کسر میگردد') color = models.CharField( verbose_name='رنگ', max_length=7, blank=True, null=True) images = models.ManyToManyField(ProductImageModel, verbose_name='عکس ها') diff --git a/backend/product/permissions.py b/backend/product/permissions.py index 165c8a3..e14d4ba 100644 --- a/backend/product/permissions.py +++ b/backend/product/permissions.py @@ -30,13 +30,7 @@ class ProductAdminPermission: return request.user.shop == obj.shop def has_delete_permission(self, request, obj=None): - if request.user.is_superuser or obj == None: - return True - - if not hasattr(request.user, 'shop'): - return False - - return request.user.shop == obj.shop + return request.user.is_superuser def has_view_permission(self, request, obj=None): if request.user.is_superuser or obj == None: diff --git a/backend/templates/admin/product/bulk_subcategory_form.html b/backend/templates/admin/product/bulk_subcategory_form.html new file mode 100644 index 0000000..3c8b916 --- /dev/null +++ b/backend/templates/admin/product/bulk_subcategory_form.html @@ -0,0 +1,86 @@ +{% extends "admin/base_site.html" %} +{% load static %} + +{% block content %} +
+ تعداد کل: {{ products|length }} محصول +
+