Files
hossein-por-shop/backend/product/admin.py
T
Parsa Nazer d29ed8e35b feat: add profit and special discount fields to ProductVariant model
- Updated ProductVariant model to include 'profit' and 'special_discount_percent' fields.
- Added corresponding fields in the admin interface for ProductVariant.
- Created migration to add new fields to the database.

feat: implement special discount code functionality in cart

- Added composables for submitting and deleting special discount codes.
- Updated CartSummary and CartItem components to handle special discount codes.
- Enhanced API endpoints to support special discount operations.
- Updated global types to include special discount code details in the cart.
2025-11-15 11:00:33 +03:30

353 lines
11 KiB
Python

from django.contrib import admin, messages
# from product.tasks import update_prices
from .models import *
from unfold.admin import TabularInline, StackedInline
from home.models import LearnVideoModel
from import_export.admin import ImportExportModelAdmin
from unfold.contrib.import_export.forms import ExportForm, ImportForm, SelectableFieldsExportForm
from unfold.contrib.forms.widgets import ArrayWidget, WysiwygWidget
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 .permissions import ProductDetailCategoryPermission
@admin.register(ProductDetailCategory)
class ProductDetailCategoryAdmin(ModelAdmin, ImportExportModelAdmin):
import_form_class = ImportForm
export_form_class = ExportForm
search_fields = ['title']
compressed_fields = True
warn_unsaved_form = True
formfield_overrides = {
ArrayField: {
"widget": ArrayWidget,
}
}
def has_add_permission(self, request):
return request.user.is_superuser
@admin.register(InPackItems)
class InPackItemsAdmin(ModelAdmin, ImportExportModelAdmin):
import_form_class = ImportForm
export_form_class = ExportForm
search_fields = ['item_title']
compressed_fields = True
warn_unsaved_form = True
formfield_overrides = {
ArrayField: {
"widget": ArrayWidget,
}
}
from account.models import ShopModel
@admin.register(ShopModel)
class ShopModelAdmin(ModelAdmin, ImportExportModelAdmin):
search_fields = ['name']
compressed_fields = True
warn_unsaved_form = True
formfield_overrides = {
ArrayField: {
"widget": ArrayWidget,
}
}
class AttributeValueInLine(StackedInline):
model = AttributeValue
extra = 0
show_change_link = True
min_num = 1
# autocomplete_fields = ['product_attributes', 'in_pack_items', 'images']
# search_fields = ['']
@admin.register(AttributeType)
class AttributeTypeAdmin(ModelAdmin, ImportExportModelAdmin):
import_form_class = ImportForm
export_form_class = ExportForm
search_fields = ['name']
compressed_fields = True
warn_unsaved_form = True
inlines = [AttributeValueInLine]
formfield_overrides = {
ArrayField: {
"widget": ArrayWidget,
}
}
@admin.register(AttributeValue)
class AttributeValueAdmin(ModelAdmin, ImportExportModelAdmin):
import_form_class = ImportForm
export_form_class = ExportForm
search_fields = ['value', 'attribute_type__name']
compressed_fields = True
warn_unsaved_form = True
formfield_overrides = {
ArrayField: {
"widget": ArrayWidget,
}
}
# def get_form(self, request, obj=None, change=False, **kwargs):
# form = super().get_form(request, obj, change, **kwargs)
# form.base_fields["color"].widget = UnfoldAdminColorInputWidget()
# return form
@admin.register(ProductImageModel)
class ProductImagesAdmin(ModelAdmin):
import_form_class = ImportForm
export_form_class = ExportForm
search_fields = ['name']
compressed_fields = True
warn_unsaved_form = True
list_display = ['display_image', 'name',]
formfield_overrides = {
ArrayField: {
"widget": ArrayWidget,
}
}
@display(description='محصول', header=True)
def display_image(self, instance):
if instance and instance.image:
image = instance.image.url
else:
image = None
return [
instance.name,
None,
None,
{
"path": image,
"height": 30,
"width": 30,
"borderless": True,
# "squared": True,
},
]
@admin.register(DetailModel)
class DetailModelAdmin(ModelAdmin, ImportExportModelAdmin):
import_form_class = ImportForm
export_form_class = ExportForm
search_fields = ['title']
compressed_fields = True
warn_unsaved_form = True
formfield_overrides = {
ArrayField: {
"widget": ArrayWidget,
}
}
class DetailInLine(StackedInline):
model = DetailModel
extra = 0
show_change_link = True
min_num = 1
max_num = 4
@admin.register(ProductDetailModel)
class ProductDetailModel1Admin(ModelAdmin, ImportExportModelAdmin):
import_form_class = ImportForm
export_form_class = ExportForm
search_fields = ['detail_category__title', 'name']
compressed_fields = True
warn_unsaved_form = True
autocomplete_fields = ['detail_category',]
inlines = [DetailInLine]
formfield_overrides = {
ArrayField: {
"widget": ArrayWidget,
}
}
class ProductVariantInLine(StackedInline):
model = ProductVariant
extra = 0
show_change_link = True
tab = True
min_num = 1
readonly_fields = ['price']
# inlines = [DetailModelInLine]
autocomplete_fields = ['product_attributes', 'in_pack_items', 'images', 'details']
fields = ['images', 'video','input_price', 'min_price', 'currency', 'price', 'discount','in_stock', 'color', 'product_attributes', 'in_pack_items', 'details', 'sell', 'slider_category', 'profit', 'special_discount_percent']
# search_fields = ['']
def formfield_for_dbfield(self, db_field, request, **kwargs):
if db_field.name == 'color':
kwargs['widget'] = UnfoldAdminColorInputWidget()
return super().formfield_for_dbfield(db_field, request, **kwargs)
from unfold.contrib.filters.admin import RelatedDropdownFilter
@admin.register(ProductVariant)
class ProductVariantAdmin(ModelAdmin, ImportExportModelAdmin):
import_form_class = ImportForm
export_form_class = ExportForm
autocomplete_fields = ['product_attributes', 'images', 'in_pack_items', 'details']
warn_unsaved_form = True
readonly_fields = ['price', 'created_at']
list_filter = [('product__category', RelatedDropdownFilter), ('product__category__parent', RelatedDropdownFilter), ('product', RelatedDropdownFilter)]
list_filter_submit = True
list_display = ('product', 'created_at')
# inlines = [DetailModelInLine]
@admin.register(ProductModel)
class ProductModelAdmin(ModelAdmin, ImportExportModelAdmin):
import_form_class = ImportForm
export_form_class = ExportForm
inlines = [ProductVariantInLine]
readonly_fields = ('slug', 'created_at')
search_fields = ['name', 'description', ]
list_filter = ['show', ('category', RelatedDropdownFilter), 'show_in_bot', ('category__parent', RelatedDropdownFilter)]
list_filter_submit = True
autocomplete_fields = ['related_products', 'shop']
# compressed_fields = True
warn_unsaved_form = True
actions_list = ['redirect_to_learn', 'update_products_price']
list_display = ['display_image', 'display_price', 'view', 'show', 'rating', 'category', 'created_at']
fieldsets = (
('فیلد های اصلی', {'fields': ('name', 'description', 'category', 'image', 'related_products', 'show', 'shop', 'show_in_bot', 'bot_banner'), "classes": ["tab"],}),
('فیلد های سيو', {'fields': ('meta_description', 'meta_keywords', 'meta_rating', 'slug'), "classes": ["tab"],}),
('فیلد های مربوط به کاربر', {'fields': ('rating', 'view',), "classes": ["tab"],}),
# ('فیلد های ایتم های پک', {'fields': ('in_pack_items', ), "classes": ["tab"],})
)
formfield_overrides = {
models.TextField: {
"widget": WysiwygWidget,
},
ArrayField: {
"widget": ArrayWidget,
}
}
def display_price(self, obj):
if obj.variants.all().first():
return obj.variants.all().first().price
display_price.short_description = 'قیمت تومانی'
@display(description='محصول', header=True)
def display_image(self, instance):
if instance and instance.variants.first() and instance.variants.first().images.first():
image = instance.variants.first().images.first().image.url if instance.variants.first().images.first().image else None
else:
image = None
return [
instance.name,
None,
None,
{
"path": image,
"height": 30,
"width": 30,
"borderless": True,
# "squared": True,
},
]
@action(description=f"اپدیت قیمت ها")
def update_products_price(self, request):
# update_prices()
messages.success(request, f"قیمت {ProductVariant.objects.all().count()} تنوع محصول اپدیت شد")
return redirect("admin:product_productmodel_changelist")
# @display(
# description=("نمایش در صفحه ی اصلی"),
# label={
# True: "danger",
# False: "success",
# },
# )
# def display_show(self, instance):
# return instance.show
@admin.register(MainCategoryModel)
class MainCategoryModelAdmin(ModelAdmin, ImportExportModelAdmin):
import_form_class = ImportForm
export_form_class = ExportForm
list_display = ['name', ]
readonly_fields = ('slug', )
search_fields = ['name', 'slug']
compressed_fields = True
warn_unsaved_form = True
formfield_overrides = {
ArrayField: {
"widget": ArrayWidget,
}
}
@admin.register(SubCategoryModel)
class SubCategoryModelAdmin(ModelAdmin, ImportExportModelAdmin):
list_display = ['name', 'parent']
search_fields = ['name', 'slug']
list_filter = ['parent', ]
import_form_class = ImportForm
export_form_class = ExportForm
readonly_fields = ('slug', )
compressed_fields = True
warn_unsaved_form = True
formfield_overrides = {
ArrayField: {
"widget": ArrayWidget,
}
}
@admin.register(CommentModel)
class CommentAdmin(ModelAdmin, ImportExportModelAdmin):
import_form_class = ImportForm
export_form_class = ExportForm
list_display = ['user', 'product', 'display_content','review_status']
search_fields = ['content',]
list_filter = ['review_status',]
compressed_fields = True
warn_unsaved_form = True
formfield_overrides = {
ArrayField: {
"widget": ArrayWidget,
}
}
radio_fields = {'review_status': admin.VERTICAL}
def display_content(self, obj):
return obj.content[0:35] + '...'
display_content.short_description = 'محتوای کامنت'
@admin.register(DollorModel)
class DollorAdmin(ModelAdmin, ImportExportModelAdmin):
import_form_class = ImportForm
export_form_class = ExportForm
exclude = ('unique_filed', )
compressed_fields = True
warn_unsaved_form = True
formfield_overrides = {
ArrayField: {
"widget": ArrayWidget,
}
}
readonly_fields = ('price',)