o
    Udh5                     @   s   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z ddlmZ ddlmZmZ dd	lmZmZ G d
d deZG dd deeZG dd deZG dd deZdS )a
  
Accounts Models Module

This module contains all user-related models including:
- Custom User model with extended functionality
- Role model for dynamic role management
- Permission model for granular access control
- Profile model for additional user information

    )models)reverse)timezone)RegexValidator)gettext_lazy)ContentType)AbstractUser
Permission)	BaseModelTimeStampedModelc                   @   s   e Zd ZdZejddededdZejdededd	Z	ej
eded
edd	ZejdededdZejdededdZG dd dZdd Zdd Zdd ZdS )Rolez
    Role model for dynamic role management.
    
    This model allows creating custom roles with specific permissions
    that can be assigned to users for flexible access control.
    d   Tz	Role NamezUnique name for the role)
max_lengthuniqueverbose_name	help_textDescriptionz Detailed description of the roleblankr   r   ZPermissionsz"Specific permissions for this role	Is Activez%Whether this role is currently activedefaultr   r   r   Priorityz#Higher number means higher priorityc                   @   s(   e Zd ZedZedZddgZdZdS )z	Role.Metar   ZRolesz	-prioritynameZaccounts_roleN)__name__
__module____qualname___r   verbose_name_pluralorderingdb_table r!   r!   HC:\Users\vibe-look\OneDrive\Desktop\Adtlas_V\src\apps\accounts\models.pyMetaF   s
    r#   c                 C   s   | j  d| j dS )z"String representation of the role.z (Priority: )N)r   priorityselfr!   r!   r"   __str__L      zRole.__str__c                 C   s   t | jjdddS )z+Get list of permission names for this role.codenameTflatN)listpermissionsvalues_listr&   r!   r!   r"   get_permissions_listP   r)   zRole.get_permissions_listc                 C   s   | j j|d S )z&Check if role has specific permission.)r*   N)r.   filterexistsr'   permission_codenamer!   r!   r"   has_permissionT      zRole.has_permissionN)r   r   r   __doc__r   	CharFieldr   r   	TextFielddescriptionManyToManyFieldr	   r.   BooleanField	is_activePositiveIntegerFieldr%   r#   r(   r0   r5   r!   r!   r!   r"   r      sB    r   c                       sD  e Zd ZdZejeddeddZededdZ	ej
ed	e	gd
ddeddZejedededdZejdededdZejddededdZejddededdZdZg dZG dd dZdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Z  fd/d0Z! fd1d2Z"d3d4 Z#  Z$S )5Userz
    Custom User model extending Django's AbstractUser.
    
    This model provides additional fields and functionality
    for comprehensive user management including roles and profiles.
    zEmail AddressTz%User's email address - used for login)r   r   z^\+?1?\d{9,15}$zRPhone number must be entered in the format: '+999999999'. Up to 15 digits allowed.)regexmessagezPhone Number   zUser's phone number)
validatorsr   r   nullr   z
User RoleszRoles assigned to this userr   FzIs Verifiedz$Whether the user's email is verifiedr   zLast Login IPzIP address of last loginrD   r   r   r   zEmail Verified AtzWhen the email was verifiedemail)username
first_name	last_namec                   @   sP   e Zd ZedZedZdgZdZej	dgdej	ddgdej	d	gdgZ
d
S )z	User.Metar?   Usersz-date_joinedZaccounts_userrF   fieldsr=   is_verifieddate_joinedN)r   r   r   r   r   r   r   r    r   Indexindexesr!   r!   r!   r"   r#      s    r#   c                 C   s   |    d| j dS )z"String representation of the user.z (r$   N)get_full_namerF   r&   r!   r!   r"   r(      s   zUser.__str__c                 C   s   | j  d| j  p| jS )zGet user's full name. N)rH   rI   striprG   r&   r!   r!   r"   rQ         zUser.get_full_namec                 C   s   | j p| jS )zGet user's short name.N)rH   rG   r&   r!   r!   r"   get_short_name   s   zUser.get_short_namec                 C   s   t | jjddjdddS )zGet list of user's role names.Tr=   r   r+   N)r-   rolesr1   r/   r&   r!   r!   r"   get_user_roles   rT   zUser.get_user_rolesc                 C   s   | j j|dd S )z Check if user has specific role.T)r   r=   N)rW   r1   r2   )r'   Z	role_namer!   r!   r"   has_role   r)   zUser.has_rolec                 C   s0   t  }| jjddD ]	}||  q
t|S )z&Get all permissions from user's roles.TrV   N)setrW   r1   updater0   r-   )r'   r.   roler!   r!   r"   get_all_permissions   s   zUser.get_all_permissionsc                    s    t  fdd| jjddD S )z4Check if user has specific permission through roles.c                 3   s    | ]}|  V  qd S )N)r5   ).0r\   r4   r!   r"   	<genexpr>   s
    
z&User.has_permission.<locals>.<genexpr>TrV   N)anyrW   r1   r3   r!   r_   r"   r5      s   zUser.has_permissionc                 C   s$   d| _ t | _| jddgd dS )zMark user's email as verified.TrM   email_verified_atupdate_fieldsN)rM   r   nowrb   saver&   r!   r!   r"   verify_email   s   
zUser.verify_emailc                 C   s   || _ | jdgd dS )z$Update user's last login IP address.last_login_iprc   N)rh   rf   )r'   
ip_addressr!   r!   r"   update_last_login_ip   s   zUser.update_last_login_ipc                    s$   t    | jr| j | _dS dS )zValidate the model data.N)supercleanrF   lowerr&   	__class__r!   r"   rl      s   
z
User.cleanc                    s   |    t j|i | dS )z"Override save to add custom logic.N)
full_cleanrk   rf   )r'   argskwargsrn   r!   r"   rf      s   z	User.savec                 C   s   t dd| jidS z-Return the absolute URL for the user profile.zaccounts:profilepk)rr   N)r   rt   r&   r!   r!   r"   get_absolute_url   r6   zUser.get_absolute_url)%r   r   r   r7   r   
EmailFieldr   rF   r   Zphone_regexr8   Zphone_numberr;   r   rW   r<   rM   GenericIPAddressFieldrh   DateTimeFieldrb   USERNAME_FIELDREQUIRED_FIELDSr#   r(   rQ   rU   rX   rY   r]   r5   rg   rj   rl   rf   ru   __classcell__r!   r!   rn   r"   r?   Y   sr    
r?   c                   @   s  e Zd ZdZejeejdededdZ	ej
eddded	d
Zejedddedd
ZejeddddeddZejddededdZej
edddedd
Zej
edddedd
ZejdededdZej
edddedd
Zej
eddded d
Zej
ed!dded!d
Zej
ed"dded#d
Zej
ed$d%ded&d
Zej
ed'dded'd
Zejded(ed)d*Zejded+ed,d*Zejd-ed.ed/d*ZG d0d1 d1Z d2d3 Z!d4d5 Z"d6d7 Z#d8d9 Z$d:S );Profilez
    Extended user profile model for additional user information.
    
    This model stores additional user data that doesn't belong
    in the core User model, following the principle of separation of concerns.
    Zprofiler?   zAssociated user account)	on_deleterelated_namer   r   z	Job Titler   TzUser job title or position)r   r   r   Z	Biographyi  zUser's biography or descriptionZAvatarzavatars/%Y/%m/zUser's profile picture)	upload_tor   rD   r   z
Birth DatezUser's birth daterE   ZCompanyzUser company or organizationZ
Departmentz"User department within the companyZWebsitezUser's website URLr   zAddress Line 1   zStreet addresszAddress Line 2zApartment, suite, etc.ZCityzState/ProvincezState or provincezPostal Code   zZIP or postal codeZCountryzPublic Profilez'Whether the profile is publicly visibler   zEmail NotificationszReceive email notificationsFzSMS NotificationszReceive SMS notificationsc                   @   s&   e Zd ZedZedZdZdgZdS )zProfile.MetazUser ProfilezUser ProfilesZaccounts_profile-created_atN)r   r   r   r   r   r   r    r   r!   r!   r!   r"   r#   i  s
    
r#   c                 C   s   | j   dS )z*String representation of the user profile.z
's ProfileN)userrQ   r&   r!   r!   r"   r(   o  s   zProfile.__str__c                 C   s@   | j rt  }|j| j j |j|jf| j j| j jfk  S dS )z%Calculate user's age from birth date.N)
birth_dater   re   dateyearmonthday)r'   todayr!   r!   r"   get_ages  s   zProfile.get_agec                 C   s   | j r| j jS dS )z!Get avatar URL or default avatar.z!/static/images/default-avatar.pngN)avatarurlr&   r!   r!   r"   get_avatar_url|  s   zProfile.get_avatar_urlc                 C   s   t dd| jjidS rs   )r   r   rt   r&   r!   r!   r"   ru     r)   zProfile.get_absolute_urlN)%r   r   r   r7   r   OneToOneFieldr?   CASCADEr   r   r8   Z	job_titler9   Zbio
ImageFieldr   	DateFieldr   ZcompanyZ
departmentURLFieldZwebsiteZaddress_line1Zaddress_line2ZcitystateZpostal_codecountryr<   Zis_profile_publicZemail_notificationsZsms_notificationsr#   r(   r   r   ru   r!   r!   r!   r"   r|      s    			r|   c                   @   s   e Zd ZdZejeejdeddZ	ej
edddedd	Zejed
eddZejededdZejeddeddZejededdZG dd dZdd Zdd Zdd ZdS )UserSessionzTrack user sessions for security and analytics.
    
    This model stores information about user login sessions
    for security monitoring and analytics purposes.
    sessionszUser who owns this session)r}   r~   r   zSession Key(   TzDjango session key)r   r   r   z
IP AddresszIP address of the session)r   z
User AgentzBrowser user agent stringr   z'Whether the session is currently active)r   r   z
Expires AtzWhen the session expiresc                   @   sL   e Zd ZedZedZdgZejddgdejdgdejdgdgZ	d	S )
zUserSession.MetazUser SessionzUser Sessionsr   r   r=   rK   session_key
expires_atN)
r   r   r   r   r   r   r   r   rO   rP   r!   r!   r!   r"   r#     s    r#   c                 C   s   d| j   d| j S )NzSession for z from )r   rQ   ri   r&   r!   r!   r"   r(     s   zUserSession.__str__c                 C   s   t  | jkS )z!Check if the session has expired.N)r   re   r   r&   r!   r!   r"   
is_expired  s   zUserSession.is_expiredc                 C   s   d| _ | jddgd dS )zDeactivate the session.Fr=   
updated_atrc   N)r=   rf   r&   r!   r!   r"   
deactivate  s   zUserSession.deactivateN)r   r   r   r7   r   
ForeignKeyr?   r   r   r   r8   r   rw   ri   r9   Z
user_agentr<   r=   rx   r   r#   r(   r   r   r!   r!   r!   r"   r     sF    
r   N)r7   	django.dbr   django.urlsr   django.utilsr   django.core.validatorsr   django.utils.translationr   r   "django.contrib.contenttypes.modelsr   django.contrib.auth.modelsr   r	   Zapps.common.modelsr
   r   r   r?   r|   r   r!   r!   r!   r"   <module>   s   @  %