321 lines
		
	
	
		
			No EOL
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			321 lines
		
	
	
		
			No EOL
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from django.contrib.auth import get_user_model
 | 
						||
from django.db import models
 | 
						||
from django.utils.html import format_html
 | 
						||
from django.core.validators import RegexValidator
 | 
						||
from simple_history.models import HistoricalRecords
 | 
						||
from common.models import TagModel, BaseModel, NameSlugModel
 | 
						||
from common.consts import UserRoles, BANK_CHOICES, USER_TYPE_CHOICES
 | 
						||
from locations.models import Affairs, Broker, County
 | 
						||
 | 
						||
 | 
						||
 | 
						||
# Create your models here.
 | 
						||
 | 
						||
class Role(TagModel):
 | 
						||
    class Meta:
 | 
						||
        verbose_name = "نقش"
 | 
						||
        verbose_name_plural = "نقشها"
 | 
						||
 | 
						||
 | 
						||
class Profile(BaseModel):
 | 
						||
    user = models.OneToOneField(
 | 
						||
        get_user_model(),
 | 
						||
        null=True,
 | 
						||
        on_delete=models.CASCADE,
 | 
						||
        verbose_name="کاربر",
 | 
						||
        related_name="profile"
 | 
						||
    )
 | 
						||
    national_code = models.CharField(
 | 
						||
        max_length=10,
 | 
						||
        null=True,
 | 
						||
        verbose_name="کد ملی",
 | 
						||
        blank=True,
 | 
						||
        validators=[
 | 
						||
            RegexValidator(
 | 
						||
                regex=r'^\d+$',
 | 
						||
                message='کد ملی باید فقط شامل اعداد باشد.',
 | 
						||
                code='invalid_national_code'
 | 
						||
            )
 | 
						||
        ]
 | 
						||
    )
 | 
						||
    address = models.TextField(
 | 
						||
        null=True,
 | 
						||
        verbose_name="آدرس",
 | 
						||
        blank=True
 | 
						||
    )
 | 
						||
    card_number = models.CharField(
 | 
						||
        max_length=16,
 | 
						||
        null=True,
 | 
						||
        verbose_name="شماره کارت",
 | 
						||
        blank=True,
 | 
						||
        validators=[
 | 
						||
            RegexValidator(
 | 
						||
                regex=r'^\d+$',
 | 
						||
                message='شماره کارت باید فقط شامل اعداد باشد.',
 | 
						||
                code='invalid_card_number'
 | 
						||
            )
 | 
						||
        ]
 | 
						||
    )
 | 
						||
    account_number = models.CharField(
 | 
						||
        max_length=20,
 | 
						||
        null=True,
 | 
						||
        verbose_name="شماره حساب",
 | 
						||
        blank=True,
 | 
						||
        validators=[
 | 
						||
            RegexValidator(
 | 
						||
                regex=r'^\d+$',
 | 
						||
                message='شماره حساب باید فقط شامل اعداد باشد.',
 | 
						||
                code='invalid_account_number'
 | 
						||
            )
 | 
						||
        ]
 | 
						||
    )
 | 
						||
    bank_name = models.CharField(
 | 
						||
        max_length=255,
 | 
						||
        choices=BANK_CHOICES,
 | 
						||
        null=True,
 | 
						||
        verbose_name="نام بانک",
 | 
						||
        blank=True
 | 
						||
    )
 | 
						||
    phone_number_1 = models.CharField(
 | 
						||
        max_length=11,
 | 
						||
        null=True,
 | 
						||
        verbose_name="شماره تماس ۱",
 | 
						||
        blank=True
 | 
						||
    )
 | 
						||
    phone_number_2 = models.CharField(
 | 
						||
        max_length=11,
 | 
						||
        null=True,
 | 
						||
        verbose_name="شماره تماس ۲",
 | 
						||
        blank=True
 | 
						||
    )
 | 
						||
    user_type = models.CharField(
 | 
						||
        max_length=20,
 | 
						||
        choices=USER_TYPE_CHOICES,
 | 
						||
        default='individual',
 | 
						||
        verbose_name="نوع کاربر"
 | 
						||
    )
 | 
						||
    company_national_id = models.CharField(
 | 
						||
        max_length=11,
 | 
						||
        null=True,
 | 
						||
        verbose_name="شناسه ملی شرکت",
 | 
						||
        blank=True,
 | 
						||
        validators=[
 | 
						||
            RegexValidator(
 | 
						||
                regex=r'^\d+$',
 | 
						||
                message='شناسه ملی باید فقط شامل اعداد باشد.',
 | 
						||
                code='invalid_company_national_id'
 | 
						||
            )
 | 
						||
        ],
 | 
						||
        help_text="فقط برای کاربران حقوقی الزامی است"
 | 
						||
    )
 | 
						||
    company_name = models.CharField(
 | 
						||
        max_length=255,
 | 
						||
        null=True,
 | 
						||
        verbose_name="نام شرکت",
 | 
						||
        blank=True,
 | 
						||
        help_text="فقط برای کاربران حقوقی الزامی است"
 | 
						||
    )
 | 
						||
 | 
						||
    pic = models.ImageField(
 | 
						||
        upload_to="profile_images",
 | 
						||
        verbose_name="تصویر",
 | 
						||
        default="../static/sample_images/profile.jpg"
 | 
						||
    )
 | 
						||
    roles = models.ManyToManyField(
 | 
						||
        Role,
 | 
						||
        verbose_name="نقشها",
 | 
						||
        blank=True,
 | 
						||
        related_name="profiles"
 | 
						||
    )
 | 
						||
    is_completed = models.BooleanField(
 | 
						||
        default=False,
 | 
						||
        verbose_name="پروفایل تکمیل شده"
 | 
						||
    )
 | 
						||
    owner = models.ForeignKey(
 | 
						||
        get_user_model(),
 | 
						||
        null=True,
 | 
						||
        on_delete=models.SET_NULL,
 | 
						||
        verbose_name="ایجاد کننده",
 | 
						||
        blank=True,
 | 
						||
        related_name="owned_profiles"
 | 
						||
    )
 | 
						||
    affairs = models.ForeignKey(
 | 
						||
        Affairs,
 | 
						||
        on_delete=models.SET_NULL,
 | 
						||
        verbose_name="امور",
 | 
						||
        null=True,
 | 
						||
        blank=True
 | 
						||
    )
 | 
						||
    county = models.ForeignKey(
 | 
						||
        County,
 | 
						||
        on_delete=models.SET_NULL,
 | 
						||
        verbose_name="شهرستان",
 | 
						||
        null=True,
 | 
						||
        blank=True
 | 
						||
        )
 | 
						||
    broker = models.ForeignKey(
 | 
						||
        Broker,
 | 
						||
        on_delete=models.SET_NULL,
 | 
						||
        verbose_name="کارگزار",
 | 
						||
        null=True,
 | 
						||
        blank=True
 | 
						||
        )
 | 
						||
 | 
						||
    history = HistoricalRecords()
 | 
						||
 | 
						||
    class Meta:
 | 
						||
        verbose_name = "پروفایل"
 | 
						||
        verbose_name_plural = "پروفایلها"
 | 
						||
 | 
						||
    def __str__(self):
 | 
						||
        return str(self.user)
 | 
						||
 | 
						||
 | 
						||
    def first_name(self):
 | 
						||
        return self.user.first_name
 | 
						||
 | 
						||
    first_name.short_description = "نام"
 | 
						||
 | 
						||
    def last_name(self):
 | 
						||
        return self.user.last_name
 | 
						||
 | 
						||
    last_name.short_description = "نام خانوادگی"
 | 
						||
 | 
						||
    def fullname(self):
 | 
						||
        return self.user.get_full_name()
 | 
						||
 | 
						||
    fullname.short_description = "نام و نام خانوادگی"
 | 
						||
 | 
						||
    def roles_str(self):
 | 
						||
        return ', '.join([role.name for role in self.roles.all()])
 | 
						||
 | 
						||
    roles_str.short_description = "نقشها"
 | 
						||
 | 
						||
    def has_role(self, role: UserRoles):
 | 
						||
        return self.roles.filter(slug=role.value).exists()
 | 
						||
 | 
						||
    def has_any_of(self, roles: list[UserRoles]):
 | 
						||
        allowed_roles = [role.value for role in roles]
 | 
						||
        return len(self.roles.filter(slug__in=allowed_roles)) > 0
 | 
						||
 | 
						||
    def has_none_of(self, roles: list[UserRoles]):
 | 
						||
        return not self.has_any_of(roles)
 | 
						||
 | 
						||
    def pic_tag(self):
 | 
						||
        return format_html(f"<img style='width:30px;' src='{self.pic.url}'>")
 | 
						||
 | 
						||
    pic_tag.short_description = "تصویر"
 | 
						||
 | 
						||
    def is_legal_entity(self):
 | 
						||
        return self.user_type == 'legal'
 | 
						||
 | 
						||
    def is_individual(self):
 | 
						||
        return self.user_type == 'individual'
 | 
						||
 | 
						||
    def get_display_name(self):
 | 
						||
        """Returns appropriate display name based on user type"""
 | 
						||
        if self.is_legal_entity() and self.company_name:
 | 
						||
            return self.company_name
 | 
						||
        return self.user.get_full_name() or str(self.user)
 | 
						||
 | 
						||
    def user_type_display(self):
 | 
						||
        return dict(USER_TYPE_CHOICES).get(self.user_type, self.user_type)
 | 
						||
 | 
						||
    user_type_display.short_description = "نوع کاربر"
 | 
						||
 | 
						||
 | 
						||
class Company(NameSlugModel):
 | 
						||
    logo = models.ImageField(
 | 
						||
        upload_to='companies/logos',
 | 
						||
        null=True,
 | 
						||
        blank=True,
 | 
						||
        verbose_name='لوگوی شرکت'
 | 
						||
        )
 | 
						||
    signature = models.ImageField(
 | 
						||
        upload_to='companies/signatures',
 | 
						||
        null=True,
 | 
						||
        blank=True,
 | 
						||
        verbose_name='امضای شرکت'
 | 
						||
        )
 | 
						||
    address = models.TextField(
 | 
						||
        null=True,
 | 
						||
        blank=True,
 | 
						||
        verbose_name='آدرس'
 | 
						||
        )
 | 
						||
    phone = models.CharField(
 | 
						||
        max_length=11,
 | 
						||
        null=True,
 | 
						||
        blank=True,
 | 
						||
        verbose_name='شماره تماس'
 | 
						||
        )
 | 
						||
    registration_number = models.CharField(
 | 
						||
        max_length=255,
 | 
						||
        null=True,
 | 
						||
        blank=True,
 | 
						||
        verbose_name='شماره ثبت شرکت'
 | 
						||
        )
 | 
						||
    broker = models.OneToOneField(
 | 
						||
        Broker,
 | 
						||
        on_delete=models.SET_NULL,
 | 
						||
        verbose_name="کارگزار",
 | 
						||
        null=True,
 | 
						||
        blank=True,
 | 
						||
        related_name='company'
 | 
						||
        )
 | 
						||
    card_number = models.CharField(
 | 
						||
        max_length=16,
 | 
						||
        null=True,
 | 
						||
        verbose_name="شماره کارت",
 | 
						||
        blank=True,
 | 
						||
        validators=[
 | 
						||
            RegexValidator(
 | 
						||
                regex=r'^\d+$',
 | 
						||
                message='شماره کارت باید فقط شامل اعداد باشد.',
 | 
						||
                code='invalid_card_number'
 | 
						||
            )
 | 
						||
        ]
 | 
						||
    )
 | 
						||
    account_number = models.CharField(
 | 
						||
        max_length=20,
 | 
						||
        null=True,
 | 
						||
        verbose_name="شماره حساب",
 | 
						||
        blank=True,
 | 
						||
        validators=[
 | 
						||
            RegexValidator(
 | 
						||
                regex=r'^\d+$',
 | 
						||
                message='شماره حساب باید فقط شامل اعداد باشد.',
 | 
						||
                code='invalid_account_number'
 | 
						||
            )
 | 
						||
        ]
 | 
						||
    )
 | 
						||
    card_holder_name = models.CharField(
 | 
						||
        max_length=255,
 | 
						||
        null=True,
 | 
						||
        verbose_name="نام دارنده کارت",
 | 
						||
        blank=True,
 | 
						||
    )
 | 
						||
    sheba_number = models.CharField(
 | 
						||
        max_length=30,
 | 
						||
        null=True,
 | 
						||
        verbose_name="شماره شبا",
 | 
						||
        blank=True,
 | 
						||
    )
 | 
						||
    bank_name = models.CharField(
 | 
						||
        max_length=255,
 | 
						||
        choices=BANK_CHOICES,
 | 
						||
        null=True,
 | 
						||
        verbose_name="نام بانک",
 | 
						||
        blank=True
 | 
						||
    )
 | 
						||
    branch_name = models.CharField(
 | 
						||
        max_length=255,
 | 
						||
        null=True,
 | 
						||
        verbose_name="شعبه بانک",
 | 
						||
        blank=True
 | 
						||
    )
 | 
						||
    class Meta:
 | 
						||
        verbose_name = 'شرکت'
 | 
						||
        verbose_name_plural = 'شرکتها'
 | 
						||
 | 
						||
    def __str__(self):
 | 
						||
        return self.name |