File size: 7,556 Bytes
3e8a166
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# management/serializers.py
# -*- coding: utf-8 -*-
from rest_framework import serializers
from django.utils import timezone
import datetime
from .models import (
    CustomUser,
    Panel,
    License,
    PushSubscription,
    MarzbanAdmin,
    SecurityToken,
    DiscountCode,
    Plan,
    Subscription,
    Payment,
    EndUser,
    PaymentMethod,
    PaymentSetting,
    PaymentDetail,
)

# --- Serializers for Django Rest Framework ---

# ADDED: LicenseSerializer (was missing)
class LicenseSerializer(serializers.ModelSerializer):
    """Serializer for the License model."""
    class Meta:
        model = License
        fields = ['key', 'is_active', 'owner', 'created_at', 'expiry_date']
        read_only_fields = ['key', 'created_at']

class CustomUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomUser
        fields = ['id', 'username', 'role']

class PushSubscriptionSerializer(serializers.Serializer):
    subscription_info = serializers.JSONField()

class MarzbanAdminSerializer(serializers.ModelSerializer):
    class Meta:
        model = MarzbanAdmin
        fields = ['id', 'username', 'password', 'permission']
        extra_kwargs = {'password': {'write_only': True}}

class SecurityTokenSerializer(serializers.ModelSerializer):
    class Meta:
        model = SecurityToken
        fields = ['admin_id', 'token', 'expiration_date']

class DiscountCodeSerializer(serializers.ModelSerializer):
    class Meta:
        model = DiscountCode
        fields = ['id', 'code', 'discount_percentage', 'is_active']
        read_only_fields = ['id', 'admin']

class PanelSerializer(serializers.ModelSerializer):
    license_key = serializers.CharField(write_only=True, required=True)

    class Meta:
        model = Panel
        fields = ['id', 'name', 'marzban_host', 'marzban_username', 'marzban_password', 'telegram_bot_token', 'license_key']
        read_only_fields = ['id', 'owner']

    def validate_license_key(self, value):
        owner = self.context['request'].user
        try:
            license_obj = License.objects.get(key=value, owner=owner, is_active=True)
            if hasattr(license_obj, 'linked_panel') and license_obj.linked_panel is not None:
                raise serializers.ValidationError('This license key has already been used.')
            return license_obj
        except License.DoesNotExist:
            raise serializers.ValidationError('Invalid or inactive license key.')

    def create(self, validated_data):
        license_obj = validated_data.pop('license_key')
        panel = Panel.objects.create(
            owner=self.context['request'].user,
            license=license_obj,
            **validated_data
        )
        return panel

class PlanSerializer(serializers.ModelSerializer):
    class Meta:
        model = Plan
        fields = ['id', 'name', 'price', 'duration_days', 'data_limit_gb', 'is_active']
        read_only_fields = ['id']

class SubscriptionSerializer(serializers.ModelSerializer):
    end_user = serializers.CharField(source='end_user.username', read_only=True)
    plan = PlanSerializer(read_only=True)
    
    class Meta:
        model = Subscription
        fields = ['id', 'end_user', 'plan', 'status', 'start_date', 'end_date', 'remaining_data_gb']

class AdminLevel3SubscriptionSerializer(serializers.ModelSerializer):
    end_user_username = serializers.CharField(write_only=True)
    plan_id = serializers.IntegerField(write_only=True)
    end_user = SubscriptionSerializer(source='end_user', read_only=True) # To show user details on response
    plan = PlanSerializer(read_only=True) # To show plan details on response

    class Meta:
        model = Subscription
        fields = ['id', 'end_user_username', 'plan_id', 'status', 'start_date', 'end_date', 'remaining_data_gb', 'end_user', 'plan']
        read_only_fields = ['id', 'status', 'start_date', 'end_date', 'remaining_data_gb', 'end_user', 'plan']

    def validate(self, data):
        request_user = self.context['request'].user
        try:
            panel = request_user.owned_panel
        except Panel.DoesNotExist:
            raise serializers.ValidationError("Admin does not own a panel.")

        try:
            end_user = EndUser.objects.get(username=data.get('end_user_username'), panel=panel)
            data['end_user_instance'] = end_user
        except EndUser.DoesNotExist:
            raise serializers.ValidationError({"end_user_username": "User not found in your panel."})

        try:
            plan = Plan.objects.get(id=data.get('plan_id'), is_active=True, panel=panel)
            data['plan_instance'] = plan
        except Plan.DoesNotExist:
            raise serializers.ValidationError({"plan_id": "Plan not found or is not active in your panel."})
            
        data['panel_instance'] = panel
        return data

    def create(self, validated_data):
        end_user = validated_data.get('end_user_instance')
        plan = validated_data.get('plan_instance')
        panel = validated_data.get('panel_instance')
        
        start_date = timezone.now().date()
        end_date = start_date + datetime.timedelta(days=plan.duration_days)
        
        subscription = Subscription.objects.create(
            end_user=end_user,
            plan=plan,
            panel=panel,
            status='active', # Assuming direct creation by admin activates it
            start_date=start_date,
            end_date=end_date,
            remaining_data_gb=plan.data_limit_gb
        )
        return subscription

class PurchaseSubscriptionForUserSerializer(serializers.Serializer):
    end_user_username = serializers.CharField(max_length=150)
    plan_id = serializers.IntegerField()
    amount = serializers.DecimalField(max_digits=10, decimal_places=2) 
    
    def validate_plan_id(self, value):
        if not Plan.objects.filter(id=value, is_active=True).exists():
            raise serializers.ValidationError("Plan not found or is not active.")
        return value

class ReceiptUploadSerializer(serializers.ModelSerializer):
    payment_token = serializers.UUIDField(write_only=True)

    class Meta:
        model = Payment
        fields = ['receipt_image', 'receipt_text', 'payment_token']
    
    def validate(self, data):
        if not data.get('receipt_image') and not data.get('receipt_text'):
            raise serializers.ValidationError("Either receipt image or text is required.")
        return data

# --- Payment System Serializers ---

class PaymentMethodSerializer(serializers.ModelSerializer):
    class Meta:
        model = PaymentMethod
        fields = ['id', 'name', 'is_active', 'can_be_managed_by_level3']
        read_only_fields = ['id']

class PaymentDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = PaymentDetail
        fields = ['id', 'card_number', 'card_holder_name', 'wallet_address']
        read_only_fields = ['id']

class EndUserPaymentDetailSerializer(serializers.Serializer):
    method_name = serializers.CharField(source='payment_method.get_name_display')
    method_key = serializers.CharField(source='payment_method.name')
    is_active = serializers.BooleanField(source='is_active')
    card_number = serializers.CharField(source='admin_level_3.payment_details.card_number', read_only=True)
    card_holder_name = serializers.CharField(source='admin_level_3.payment_details.card_holder_name', read_only=True)
    wallet_address = serializers.CharField(source='admin_level_3.payment_details.wallet_address', read_only=True)