from django.db import IntegrityError from django.db.transaction import atomic from rest_framework import serializers from rest_framework.exceptions import APIException from .constans import TypeChoices from .models import Transaction from ..gooyal_oauth2.models import Application from ..users.models import User class BaseTransactionSerializer(serializers.ModelSerializer): payee_id = serializers.UUIDField(read_only=True) payee_type = serializers.UUIDField(read_only=True) role = serializers.SerializerMethodField() class Meta: model = Transaction fields = ('uuid', 'payer_id', 'payer_type', 'payee_id', 'payee_type', "created_at", "state", 'amount', 'delay', 'updated_at', 'details', 'role' ) read_only_fields = ['uuid', 'updated_at', 'state', 'created_at', 'details', 'role'] def to_representation(self, instance): instance.update_details() return super().to_representation(instance) class UserTransactionSerializer(BaseTransactionSerializer): def get_role(self, obj: Transaction) -> int: request = self.context.get('request') user = request.user return obj.get_role(user) class DepositSerializer(serializers.ModelSerializer): uuid = serializers.UUIDField(required=True) class Meta: model = Transaction fields = ( 'uuid', 'payer', 'payee', "created_at", "state", 'amount', 'delay', 'updated_at', # 'detail_id', ) read_only_fields = ['updated_at', 'state', 'created_at', 'payer'] # , 'detail_id'] def create(self, validated_data): with atomic(): try: transaction = Transaction.objects.create_transaction(**validated_data) transaction.submit() except IntegrityError as e: raise APIException('duplicate uuid') return transaction class WithdrawSerializer(serializers.ModelSerializer): uuid = serializers.UUIDField(required=True) class Meta: model = Transaction fields = ( 'uuid', 'payer', 'payee', "created_at", "state", 'amount', 'delay', 'updated_at', # 'detail_id', ) read_only_fields = ['updated_at', 'state', 'created_at', 'payee'] # , 'detail_id'] def create(self, validated_data): with atomic(): try: transaction = Transaction.objects.create_transaction(**validated_data) transaction.submit() except IntegrityError as e: raise APIException('duplicate uuid') return transaction class MyWalletSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['balance'] class WalletBalanceSerializer(serializers.ModelSerializer): instance_id = serializers.UUIDField(required=True) instance_type = serializers.ChoiceField(choices=TypeChoices.choices, required=True) class Meta: model = User fields = ['balance', 'instance_id', 'instance_type'] class TransferSubmitSerializer(serializers.ModelSerializer): class Meta: model = Transaction fields = ('uuid', 'payer_id', 'payer_type', 'payee_id', 'payee_type', "created_at", "state", 'amount', # 'delay', 'updated_at', 'details', ) read_only_fields = ['updated_at', 'state', 'created_at'] class TransferVerifySerializer(serializers.ModelSerializer): class Meta: model = Transaction fields = ('uuid', 'payer_id', 'payer_type', 'payee_id', 'payee_type', "created_at", "state", 'amount', # 'delay', 'updated_at', 'details', ) read_only_fields = ['uuid', 'payer_id', 'payer_type', 'payee_id', 'payee_type', 'updated_at', 'state', 'amount', 'created_at'] #### Application class ApplicationBalanceSerializer(serializers.ModelSerializer): class Meta: model = Application fields = ['balance'] class ApplicationTransactionSerializer(BaseTransactionSerializer): pass class ApplicationDepositSerializer(serializers.ModelSerializer): uuid = serializers.UUIDField(required=True) # TODO: details as fields class Meta: model = Transaction fields = ( 'uuid', 'payer_id', 'payer_type', 'payee_id', 'payee_type', "created_at", "state", 'amount', # 'delay', 'updated_at', 'details', ) read_only_fields = ['updated_at', 'state', 'created_at', 'payer_id', 'payer_type'] class ApplicationWithdrawSerializer(serializers.ModelSerializer): uuid = serializers.UUIDField(required=True) class Meta: model = Transaction fields = ( 'uuid', 'payer_id', 'payer_type', 'payee_id', 'payee_type', "created_at", "state", 'amount', # 'delay', 'updated_at', 'details', ) read_only_fields = ['updated_at', 'state', 'created_at', 'payee_id', 'payee_type', 'details']