This commit is contained in:
Phil Zhitnikov 2023-10-31 16:50:45 +04:00
parent 13ae751564
commit fce76143b4
8 changed files with 117 additions and 6 deletions

View File

@ -2,7 +2,7 @@ from django.contrib import admin
from django.contrib.admin import display
from mptt.admin import MPTTModelAdmin
from .models import Category, Checklist, GlobalSettings, PaymentMethod, Promocode, User, Image
from .models import Category, Checklist, GlobalSettings, PaymentMethod, Promocode, User, Image, Gift
@admin.register(User)
@ -52,5 +52,10 @@ class PromoCodeAdmin(admin.ModelAdmin):
list_display = ('name', 'discount', 'free_delivery', 'no_comission')
@admin.register(Gift)
class GiftAdmin(admin.ModelAdmin):
list_display = ('name', 'min_price')

14
store/filters.py Normal file
View File

@ -0,0 +1,14 @@
from django_filters import rest_framework as filters
from .models import Gift
class GiftFilter(filters.FilterSet):
for_price = filters.NumberFilter(method='filter_for_price')
class Meta:
model = Gift
fields = ('for_price',)
def filter_for_price(self, queryset, name, value):
return queryset.filter(min_price__lte=value)

View File

@ -0,0 +1,31 @@
# Generated by Django 4.2.2 on 2023-10-25 15:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('store', '0044_checklist_split_accepted'),
]
operations = [
migrations.CreateModel(
name='Gift',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100, verbose_name='Название')),
('image', models.ImageField(blank=True, null=True, upload_to='gifts/', verbose_name='Фото')),
('min_price', models.DecimalField(decimal_places=2, default=0, help_text='от какой суммы доступен подарок', max_digits=10, verbose_name='Минимальная цена')),
],
options={
'verbose_name': 'Подарок',
'verbose_name_plural': 'Подарки',
},
),
migrations.AlterField(
model_name='image',
name='type',
field=models.PositiveSmallIntegerField(choices=[(0, 'Изображение'), (1, 'Превью'), (2, 'Документ'), (3, 'Подарок')], default=0, verbose_name='Тип'),
),
]

View File

@ -0,0 +1,24 @@
# Generated by Django 4.2.2 on 2023-10-25 15:43
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('store', '0045_gift_alter_image_type'),
]
operations = [
migrations.AddField(
model_name='checklist',
name='gift',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='store.gift', verbose_name='Подарок'),
),
migrations.AlterField(
model_name='gift',
name='min_price',
field=models.DecimalField(decimal_places=2, default=0, help_text='от какой суммы доступен подарок', max_digits=10, verbose_name='Минимальная цена в юанях'),
),
]

View File

@ -204,17 +204,20 @@ class Image(models.Model):
DEFAULT = 0
PREVIEW = 1
DOC = 2
GIFT = 3
TYPE_CHOICES = (
(DEFAULT, 'Изображение'),
(PREVIEW, 'Превью'),
(DOC, 'Документ'),
(GIFT, 'Подарок'),
)
TYPE_TO_UPLOAD_PATH = {
DEFAULT: 'checklist_images/',
PREVIEW: 'checklist_images/',
DOC: 'docs/',
GIFT: 'gifts/',
}
image = models.ImageField('Файл изображения', upload_to=image_upload_path)
@ -228,6 +231,19 @@ class Image(models.Model):
return f"{self.get_type_display()}: {getattr(self.image, 'name', '')}"
class Gift(models.Model):
name = models.CharField('Название', max_length=100)
image = models.ImageField('Фото', upload_to=Image.TYPE_TO_UPLOAD_PATH[Image.GIFT], null=True, blank=True)
min_price = models.DecimalField('Минимальная цена в юанях', help_text='от какой суммы доступен подарок', max_digits=10, decimal_places=2, default=0)
def __str__(self):
return self.name
class Meta:
verbose_name = 'Подарок'
verbose_name_plural = 'Подарки'
def generate_checklist_id():
""" Generate unique id for Checklist """
@ -242,7 +258,8 @@ def generate_checklist_id():
class ChecklistQuerySet(models.QuerySet):
def with_base_related(self):
return self.select_related('manager', 'category', 'payment_method', 'promocode', 'price_snapshot')\
return self.select_related('manager', 'category', 'payment_method',
'promocode', 'price_snapshot', 'gift') \
.prefetch_related(Prefetch('images', to_attr='_images'))
def default_ordering(self):
@ -341,6 +358,7 @@ class Checklist(models.Model):
# promo
promocode = models.ForeignKey('Promocode', verbose_name='Промокод', on_delete=models.PROTECT, null=True, blank=True)
gift = models.ForeignKey('Gift', verbose_name='Подарок', on_delete=models.PROTECT, null=True, blank=True)
comment = models.CharField('Комментарий', max_length=200, null=True, blank=True)
# buyername

View File

@ -1,7 +1,7 @@
from drf_extra_fields.fields import Base64ImageField
from rest_framework import serializers
from store.models import User, Checklist, GlobalSettings, Category, PaymentMethod, Promocode, Image
from store.models import User, Checklist, GlobalSettings, Category, PaymentMethod, Promocode, Image, Gift
from store.utils import get_primary_key_related_model
@ -63,6 +63,14 @@ class CategoryFullSerializer(CategorySerializer):
fields = CategorySerializer.Meta.fields + ('children',)
class GiftSerializer(serializers.ModelSerializer):
image = Base64ImageField(required=False, allow_null=True)
class Meta:
model = Gift
fields = ('id', 'name', 'image', 'min_price')
class ChecklistSerializer(serializers.ModelSerializer):
id = serializers.CharField(read_only=True)
managerid = serializers.PrimaryKeyRelatedField(source='manager_id', read_only=True, allow_null=True)
@ -77,6 +85,8 @@ class ChecklistSerializer(serializers.ModelSerializer):
promo = serializers.SlugRelatedField(source='promocode', slug_field='name',
queryset=Promocode.objects.active(), required=False, allow_null=True)
gift = get_primary_key_related_model(GiftSerializer, required=False, allow_null=True)
currency = serializers.DecimalField(source='yuan_rate', read_only=True, max_digits=10, decimal_places=2)
curencycurency2 = serializers.DecimalField(source='price_yuan', required=False, max_digits=10, decimal_places=2)
currency3 = serializers.IntegerField(source='price_rub', read_only=True)
@ -165,7 +175,7 @@ class ChecklistSerializer(serializers.ModelSerializer):
'image',
'previewimage',
'currency', 'curencycurency2', 'currency3', 'chinadelivery', 'chinadelivery2', 'commission',
'promo',
'promo', 'gift',
'comment',
'fullprice', 'realprice',
'buyername', 'buyerphone', 'tg',

View File

@ -8,6 +8,7 @@ router = DefaultRouter()
router.register(r'statistics', views.StatisticsAPI, basename='statistics')
router.register(r'cdek', views.CDEKAPI, basename='cdek')
router.register(r'gifts', views.GiftAPI, basename='gifts')
urlpatterns = [
path("checklist/", views.ChecklistAPI.as_view()),

View File

@ -13,10 +13,11 @@ from rest_framework.response import Response
from external_api.cdek import CDEKClient
from store.exceptions import CRMException
from store.models import Checklist, GlobalSettings, Category, PaymentMethod, Promocode
from store.filters import GiftFilter
from store.models import Checklist, GlobalSettings, Category, PaymentMethod, Promocode, Gift
from store.serializers import (ChecklistSerializer, CategorySerializer, CategoryFullSerializer,
PaymentMethodSerializer, GlobalSettingsSerializer,
PromocodeSerializer, AnonymousUserChecklistSerializer)
PromocodeSerializer, AnonymousUserChecklistSerializer, GiftSerializer)
from utils.permissions import ReadOnly
@ -184,6 +185,13 @@ class PromoCodeAPI(mixins.CreateModelMixin, generics.GenericAPIView):
return Response(status=status.HTTP_204_NO_CONTENT)
class GiftAPI(viewsets.ModelViewSet):
queryset = Gift.objects.all()
serializer_class = GiftSerializer
permission_classes = [IsAuthenticated | ReadOnly]
filterset_class = GiftFilter
class StatisticsAPI(viewsets.GenericViewSet):
def get_queryset(self):
return Checklist.objects.all() \