deepsite / management /models.py
coerxso's picture
Upload 73 files
3e8a166 verified
raw
history blame
10.6 kB
# management/models.py
# -*- coding: utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
import uuid
import datetime
# --- Users & Authentication ---
class CustomUser(AbstractUser):
ROLE_CHOICES = [
('SuperAdmin', 'Super Admin'),
('PanelOwner', 'Panel Owner'),
('AdminLevel2', 'Admin Level 2'),
('AdminLevel3', 'Admin Level 3'),
('EndUser', 'End User'),
]
role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='EndUser')
marzban_admin_id = models.UUIDField(null=True, blank=True)
def is_super_admin(self):
return self.role == 'SuperAdmin'
def is_admin_level_2(self):
return self.role in ('SuperAdmin', 'PanelOwner', 'AdminLevel2')
def is_admin_level_3(self):
return self.role in ('SuperAdmin', 'PanelOwner', 'AdminLevel2', 'AdminLevel3')
def __str__(self):
return self.username
# --- Main Website Models ---
class AdminLevel2(models.Model):
user = models.OneToOneField(
CustomUser, on_delete=models.CASCADE, related_name='admin_level_2'
)
telegram_chat_id = models.CharField(
max_length=255, blank=True, null=True,
verbose_name="تلگرام چت آیدی"
)
license_expiry_date = models.DateField(
null=True, blank=True, verbose_name="تاریخ انقضای لایسنس"
)
def __str__(self):
return f"Admin Level 2: {self.user.username}"
class AdminLevel3(models.Model):
user = models.OneToOneField(
CustomUser, on_delete=models.CASCADE, related_name='admin_level_3'
)
parent_admin = models.ForeignKey(
AdminLevel2,
on_delete=models.CASCADE,
related_name='child_admins',
verbose_name="ادمین والد (سطح ۲)"
)
telegram_chat_id = models.CharField(
max_length=255, blank=True, null=True,
verbose_name="تلگرام چت آیدی"
)
def __str__(self):
return f"Admin Level 3: {self.user.username}"
class Panel(models.Model):
owner = models.OneToOneField(CustomUser, on_delete=models.CASCADE, related_name='owned_panel')
name = models.CharField(max_length=255, verbose_name="نام پنل")
marzban_host = models.CharField(max_length=255, verbose_name="آدرس هاست Marzban")
marzban_username = models.CharField(max_length=255, verbose_name="نام کاربری Marzban")
marzban_password = models.CharField(max_length=255, verbose_name="رمز عبور Marzban")
telegram_bot_token = models.CharField(max_length=255, blank=True, null=True)
# ADDED: Link to the license
license = models.OneToOneField('License', on_delete=models.SET_NULL, null=True, blank=True, related_name='linked_panel')
def __str__(self):
return self.name
class License(models.Model):
key = models.UUIDField(default=uuid.uuid4, editable=False, unique=True, verbose_name="کلید لایسنس")
is_active = models.BooleanField(default=True, verbose_name="وضعیت فعال")
owner = models.ForeignKey(CustomUser, on_delete=models.CASCADE, verbose_name="صاحب لایسنس")
created_at = models.DateTimeField(auto_now_add=True, verbose_name="تاریخ ایجاد")
expiry_date = models.DateField(verbose_name="تاریخ انقضا")
def __str__(self):
return str(self.key)
# ADDED: MarzbanAdmin model (was missing)
class MarzbanAdmin(models.Model):
username = models.CharField(max_length=255, unique=True)
password = models.CharField(max_length=255)
permission = models.CharField(max_length=50)
panel = models.ForeignKey(Panel, on_delete=models.CASCADE, related_name='marzban_admins')
def __str__(self):
return self.username
# ADDED: MarzbanUser model (was missing)
class MarzbanUser(models.Model):
username = models.CharField(max_length=255, unique=True)
# Add other fields relevant to Marzban users
# ...
def __str__(self):
return self.username
class EndUser(models.Model):
username = models.CharField(max_length=255, unique=True)
panel = models.ForeignKey(Panel, on_delete=models.CASCADE)
# marzban_user_id can be nullable if the user is created first in our DB
marzban_user_id = models.CharField(max_length=255, unique=True, null=True, blank=True)
telegram_chat_id = models.CharField(max_length=255, blank=True, null=True)
def __str__(self):
return self.username
# ADDED: Plan model (was missing)
class Plan(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
duration_days = models.IntegerField()
data_limit_gb = models.FloatField()
is_active = models.BooleanField(default=True)
panel = models.ForeignKey(Panel, on_delete=models.CASCADE, related_name='plans')
def __str__(self):
return f"{self.name} ({self.panel.name})"
# ADDED: Subscription model (was missing)
class Subscription(models.Model):
STATUS_CHOICES = [
('active', 'فعال'),
('expired', 'منقضی شده'),
('pending', 'در انتظار پرداخت'),
('deactivated', 'غیرفعال'),
]
end_user = models.ForeignKey(EndUser, on_delete=models.CASCADE, related_name='subscriptions')
plan = models.ForeignKey(Plan, on_delete=models.PROTECT) # Don't delete plan if subscription exists
panel = models.ForeignKey(Panel, on_delete=models.CASCADE, related_name='subscriptions')
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
start_date = models.DateField(null=True, blank=True)
end_date = models.DateField(null=True, blank=True)
remaining_data_gb = models.FloatField(null=True, blank=True)
def __str__(self):
return f"Subscription for {self.end_user.username} on plan {self.plan.name}"
# FIXED: Complete overhaul of the Payment model
class Payment(models.Model):
STATUS_CHOICES = [
('pending', 'در انتظار تأیید'),
('approved', 'تأیید شده'),
('rejected', 'رد شده'),
]
subscription = models.ForeignKey(Subscription, on_delete=models.CASCADE, related_name='payments')
admin = models.ForeignKey(CustomUser, on_delete=models.PROTECT, related_name='handled_payments') # The admin to approve
amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="مبلغ")
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending', verbose_name="وضعیت")
created_at = models.DateTimeField(auto_now_add=True, verbose_name="تاریخ ایجاد")
# Fields for receipt upload
payment_token = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
receipt_image = models.ImageField(upload_to='receipts/', blank=True, null=True, verbose_name="تصویر رسید")
receipt_text = models.TextField(blank=True, null=True, verbose_name="متن رسید")
def __str__(self):
return f"Payment for {self.subscription.end_user.username} - {self.amount} - {self.status}"
class DiscountCode(models.Model):
code = models.CharField(max_length=50, unique=True)
admin = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
discount_percentage = models.DecimalField(max_digits=5, decimal_places=2)
is_active = models.BooleanField(default=True)
def __str__(self):
return self.code
# --- Telegram Integration ---
class TelegramUser(models.Model):
admin_id = models.CharField(max_length=255, unique=True, primary_key=True)
chat_id = models.CharField(max_length=255, unique=True)
username = models.CharField(max_length=255)
class Meta:
managed = False
db_table = 'telegram_users'
def __str__(self):
return self.username
class SecurityToken(models.Model):
admin_id = models.CharField(max_length=255, primary_key=True)
token = models.CharField(max_length=255, unique=True, default=uuid.uuid4)
expiration_date = models.DateTimeField()
class Meta:
managed = False
db_table = 'telegram_tokens'
def __str__(self):
return f"Token for {self.admin_id}"
# --- Push Notifications ---
class PushSubscription(models.Model):
user = models.ForeignKey(
CustomUser, on_delete=models.CASCADE, related_name='push_subscriptions'
)
subscription_info = models.JSONField()
created_at = models.DateTimeField(auto_now_add=True)
# --- Payment System Models ---
class PaymentMethod(models.Model):
METHOD_CHOICES = [
('gateway', 'Bank Gateway'),
('crypto', 'Cryptocurrency'),
('manual', 'Manual (Card-to-Card)'),
]
name = models.CharField(max_length=50, choices=METHOD_CHOICES, unique=True, verbose_name="Payment Method Name")
is_active = models.BooleanField(default=True, verbose_name="Is Active?")
can_be_managed_by_level3 = models.BooleanField(default=False, verbose_name="Can be managed by Admin Level 3?")
class Meta:
verbose_name = "Payment Method"
verbose_name_plural = "Payment Methods"
def __str__(self):
return self.get_name_display()
class PaymentSetting(models.Model):
admin_level_3 = models.ForeignKey(
CustomUser,
on_delete=models.CASCADE,
limit_choices_to={'role': 'AdminLevel3'},
related_name='payment_settings'
)
payment_method = models.ForeignKey(PaymentMethod, on_delete=models.CASCADE)
is_active = models.BooleanField(default=False, verbose_name="Is Active for this Admin?")
class Meta:
unique_together = ('admin_level_3', 'payment_method')
verbose_name = "Payment Setting"
verbose_name_plural = "Payment Settings"
def __str__(self):
return f"{self.admin_level_3.username}'s {self.payment_method.get_name_display()} Setting"
class PaymentDetail(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
admin_level_3 = models.OneToOneField(
CustomUser,
on_delete=models.CASCADE,
limit_choices_to={'role': 'AdminLevel3'},
related_name='payment_details'
)
card_number = models.CharField(max_length=50, blank=True, null=True)
card_holder_name = models.CharField(max_length=255, blank=True, null=True)
wallet_address = models.CharField(max_length=255, blank=True, null=True)
class Meta:
verbose_name = "Payment Detail"
verbose_name_plural = "Payment Details"
def __str__(self):
return f"Payment details for {self.admin_level_3.username}"