111 lines
4.0 KiB
Python
111 lines
4.0 KiB
Python
from django.conf import settings
|
|
from django.db.models import Q
|
|
from djoser import serializers as djoser_serializers
|
|
from djoser.conf import settings as djoser_settings
|
|
from rest_framework import serializers
|
|
from rest_framework.exceptions import AuthenticationFailed
|
|
|
|
from .models import User, BonusProgramTransaction, BonusType
|
|
from .utils import verify_telegram_authentication
|
|
|
|
|
|
class UserSerializer(serializers.ModelSerializer):
|
|
name = serializers.CharField(source='first_name')
|
|
lastname = serializers.CharField(source='middle_name')
|
|
surname = serializers.CharField(source='last_name')
|
|
invited_with_orders_count = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = User
|
|
fields = ('id', 'email', 'phone', 'role', 'name', 'lastname', 'surname',
|
|
'balance', 'referral_code', 'is_draft_user', 'invited_with_orders_count')
|
|
|
|
def get_invited_with_orders_count(self, obj):
|
|
return obj.invited_users_with_orders.count()
|
|
|
|
|
|
class BonusProgramTransactionSerializer(serializers.ModelSerializer):
|
|
order_id = serializers.StringRelatedField(source='order.id', allow_null=True)
|
|
type = serializers.CharField(source='get_type_display')
|
|
|
|
class Meta:
|
|
model = BonusProgramTransaction
|
|
fields = ('id', 'type', 'date', 'amount', 'order_id', 'comment', 'was_cancelled')
|
|
|
|
|
|
def non_zero_validator(value):
|
|
if value == 0:
|
|
raise serializers.ValidationError("Value cannot be zero")
|
|
return value
|
|
|
|
|
|
class UserBalanceUpdateSerializer(BonusProgramTransactionSerializer):
|
|
amount = serializers.IntegerField(validators=[non_zero_validator])
|
|
type = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = BonusProgramTransactionSerializer.Meta.model
|
|
fields = BonusProgramTransactionSerializer.Meta.fields
|
|
read_only_fields = ('id', 'type', 'date')
|
|
|
|
def get_type(self, instance):
|
|
# Deposit or spent depending on value
|
|
if instance['amount'] < 0:
|
|
return BonusType.OTHER_WITHDRAWAL
|
|
elif instance['amount'] > 0:
|
|
return BonusType.OTHER_DEPOSIT
|
|
|
|
|
|
class SetInitialPasswordSerializer(djoser_serializers.PasswordSerializer):
|
|
def validate(self, attrs):
|
|
user = getattr(self, "user", None) or self.context["request"].user
|
|
# why assert? There are ValidationError / fail everywhere
|
|
assert user is not None
|
|
|
|
if not user.is_superuser and not user.is_draft_user:
|
|
raise serializers.ValidationError("To change password, use /users/change_password endpoint")
|
|
|
|
return super().validate(attrs)
|
|
|
|
|
|
class UserCreateSerializer(djoser_serializers.UserCreateSerializer):
|
|
email = serializers.EmailField(required=True)
|
|
|
|
|
|
class TokenCreateSerializer(serializers.Serializer):
|
|
email_or_phone = serializers.CharField()
|
|
password = serializers.CharField(required=False, style={"input_type": "password"})
|
|
|
|
default_error_messages = {
|
|
"invalid_credentials": djoser_settings.CONSTANTS.messages.INVALID_CREDENTIALS_ERROR,
|
|
"inactive_account": djoser_settings.CONSTANTS.messages.INACTIVE_ACCOUNT_ERROR,
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.user = None
|
|
|
|
def validate(self, attrs):
|
|
email_or_phone = attrs.get('email_or_phone')
|
|
password = attrs.get("password")
|
|
|
|
user = User.objects.filter(Q(email=email_or_phone) | Q(phone=email_or_phone)).first()
|
|
if not user or not user.check_password(password) or not user.is_active:
|
|
raise AuthenticationFailed()
|
|
|
|
self.user = user
|
|
return attrs
|
|
|
|
|
|
class TelegramCallbackSerializer(serializers.Serializer):
|
|
id = serializers.IntegerField()
|
|
first_name = serializers.CharField(allow_null=True)
|
|
username = serializers.CharField(allow_null=True)
|
|
photo_url = serializers.URLField(allow_null=True)
|
|
auth_date = serializers.IntegerField()
|
|
hash = serializers.CharField()
|
|
|
|
def validate(self, attrs):
|
|
verify_telegram_authentication(bot_token=settings.TG_BOT_TOKEN, request_data=attrs)
|
|
return attrs
|