U
    (3ihM6                     @   s   d Z ddlZddlmZ ddlmZ ddlmZ G dd dej	Z
G dd	 d	ej	ZG d
d dej	ZG dd dej	ZG dd dej	ZG dd dej	ZG dd dej	ZG dd dej	ZG dd de
eeeZG dd deeeeeZdS )z
Common Models Module

This module contains base models and common functionality
that will be used across all applications in the project.

    N)models)timezone)gettext_lazyc                       s^   e Zd ZdZejeddeddZejeddeddZG d	d
 d
Z	 fddZ
  ZS )TimeStampedModelaa  Abstract base model that provides timestamp fields only.
    
    This model provides created_at and updated_at fields that are
    automatically managed. All models should inherit from this.
    
    This is a lighter version of BaseModel for cases where
    you only need timestamp tracking without user tracking
    or soft delete functionality.
    z
Created AtTz)Date and time when the record was created)auto_now_add	help_textz
Updated Atz.Date and time when the record was last updated)auto_nowr   c                   @   s   e Zd ZdZdgZdS )zTimeStampedModel.MetaTz-created_atN__name__
__module____qualname__abstractordering r   r   ./var/www/html/Adtlas/src/apps/common/models.pyMeta(   s   r   c                    s$   | j jst | _t j|| dS )z"Override save to add custom logic.N)_stateaddingr   now
updated_atsupersave)selfargskwargs	__class__r   r   r   ,   s    
zTimeStampedModel.save)r
   r   r   __doc__r   DateTimeField_
created_atr   r   r   __classcell__r   r   r   r   r      s   r   c                   @   s6   e Zd ZdZejdejdeddZ	G dd dZ
dS )		UUIDModelzAbstract base model that provides UUID primary key.
    
    This model uses UUID as the primary key instead of auto-incrementing
    integers for better security and distributed systems compatibility.
    TFz!Unique identifier for this record)primary_keydefaulteditabler   c                   @   s   e Zd ZdZdS )zUUIDModel.MetaTNr
   r   r   r   r   r   r   r   r   D   s   r   N)r
   r   r   r   r   	UUIDFielduuiduuid4r   idr   r   r   r   r   r"   5   s   r"   c                       s   e Zd ZdZejeddeddZejedddedd	Z	ej
d
ejdddeddZG dd dZd fdd	ZdddZdddZedd Zedd Z  ZS )SoftDeleteModelzAbstract base model that provides soft delete functionality.
    
    Instead of actually deleting records, this model marks them as deleted
    and provides methods to filter out deleted records.
    z
Is DeletedFz)Whether this record has been soft deletedr$   r   z
Deleted AtTz)Date and time when the record was deleted)nullblankr   accounts.Userz%(class)s_deleted_recordszUser who deleted this record	on_deleter-   r.   related_namer   c                   @   s   e Zd ZdZdS )zSoftDeleteModel.MetaTNr&   r   r   r   r   r   f   s   r   Nc                    s   t  j||d dS )z)Override delete to implement soft delete.)usingkeep_parentsN)r   delete)r   r3   r4   r   r   r   hard_deletei   s    zSoftDeleteModel.hard_deletec                 C   s0   d| _ t | _|r|| _| jdddgd dS )z
        Perform a soft delete on this record.
        
        Args:
            user: The user performing the delete operation
        T
is_deleted
deleted_at
deleted_byupdate_fieldsN)r7   r   r   r8   r9   r   r   userr   r   r   soft_deleten   s
    
zSoftDeleteModel.soft_deletec                 C   s4   d| _ d| _d| _|r|| _| jddddgd dS )z
        Restore a soft deleted record.
        
        Args:
            user: The user performing the restore operation
        FNr7   r8   r9   
updated_byr:   )r7   r8   r9   r?   r   r<   r   r   r   restore{   s    zSoftDeleteModel.restorec                 C   s   | j jddS )z
        Get a queryset of non-deleted objects.
        
        Returns:
            QuerySet: All objects where is_deleted=False
        Fr7   objectsfilterclsr   r   r   get_active_objects   s    z"SoftDeleteModel.get_active_objectsc                 C   s   | j jddS )z
        Get a queryset of soft deleted objects.
        
        Returns:
            QuerySet: All objects where is_deleted=True
        TrA   rB   rE   r   r   r   get_deleted_objects   s    z#SoftDeleteModel.get_deleted_objects)NF)N)N)r
   r   r   r   r   BooleanFieldr   r7   r   r8   
ForeignKeySET_NULLr9   r   r6   r>   r@   classmethodrG   rH   r!   r   r   r   r   r+   H   s8   	


	r+   c                       sP   e Zd ZdZejddededdZG dd dZ fd	d
Z	dd Z
  ZS )	SlugModelz
    Abstract model that provides slug functionality.
    
    This model adds a slug field that can be used for SEO-friendly URLs.
    The slug is automatically generated from a specified field.
       TZSlugzSEO-friendly URL identifier)
max_lengthuniqueverbose_namer   c                   @   s   e Zd ZdZdS )zSlugModel.MetaTNr&   r   r   r   r   r      s   r   c                    s<   | j s*t| dr*ddlm} ||  | _ t j|| dS )z
        Override save method to auto-generate slug if not provided.
        
        Child models should define a get_slug_source() method
        that returns the field value to generate the slug from.
        get_slug_sourcer   )slugifyN)slughasattrdjango.utils.textrS   rR   r   r   )r   r   r   rS   r   r   r   r      s    zSlugModel.savec                 C   s
   t | jS )a  
        Get the source value for slug generation.
        
        This method should be overridden in child models
        to specify which field should be used for slug generation.
        
        Returns:
            str: The value to generate slug from
        )strpkr   r   r   r   rR      s    
zSlugModel.get_slug_source)r
   r   r   r   r   	SlugFieldr   rT   r   r   rR   r!   r   r   r   r   rM      s   rM   c                   @   sF   e Zd ZdZejdededdZG dd dZdd	 Z	d
d Z
dS )SortableModelz
    Abstract model that provides sorting functionality.
    
    This model adds an order field that can be used to sort records
    in a specific order defined by the user.
    r   Orderz.Order for sorting (lower numbers appear first))r$   rQ   r   c                   @   s   e Zd ZdZddgZdS )zSortableModel.MetaTorderr*   Nr	   r   r   r   r   r      s   r   c                 C   sn   zT| j jj| jdd }|rR|j}| j|_|| _|jdgd | jdgd W n tk
rh   Y nX dS )z
        Move this item up in the sort order.
        
        Swaps the order with the item that has the next lower order value.
        )Z	order__ltz-orderr]   r:   Nr   rC   rD   r]   order_byfirstr   	Exception)r   Zprevious_itemZprevious_orderr   r   r   move_up   s    zSortableModel.move_upc                 C   sn   zT| j jj| jdd }|rR|j}| j|_|| _|jdgd | jdgd W n tk
rh   Y nX dS )z
        Move this item down in the sort order.
        
        Swaps the order with the item that has the next higher order value.
        )Z	order__gtr]   r:   Nr^   )r   	next_itemZ
next_orderr   r   r   	move_down   s    zSortableModel.move_downN)r
   r   r   r   r   PositiveIntegerFieldr   r]   r   rb   rd   r   r   r   r   r[      s   r[   c                       sf   e Zd ZdZejdejdddeddZejdejdddeddZ	G d	d
 d
Z
 fddZ  ZS )
AuditModelzAbstract model that provides audit trail functionality.
    
    This model tracks who created and last modified a record.
    r/   Tz%(class)s_created_recordszUser who created this recordr0   z%(class)s_updated_recordsz!User who last updated this recordc                   @   s   e Zd ZdZdS )zAuditModel.MetaTNr&   r   r   r   r   r   &  s   r   c                    s8   t | dd}| js|r|| _|r&|| _t j|| dS )z
        Override save method to handle user tracking.
        
        This method automatically sets created_by and updated_by
        based on the current user in the request context.
        Z_current_userN)getattrrX   
created_byr?   r   r   )r   r   r   r=   r   r   r   r   )  s    
zAuditModel.save)r
   r   r   r   r   rJ   rK   r   rh   r?   r   r   r!   r   r   r   r   rf     s&   		rf   c                   @   s   e Zd ZdZdedfdedfdedfded	fd
edfgZejeddededdZej	eddeddZ
G dd dZdd Zdd Zdd Zdd ZdS )StatusModelzAbstract model that provides status functionality.
    
    This model provides common status fields used across the application.
    activeZActiveinactiveZInactivependingZPending	suspendedZ	SuspendedarchivedZArchivedStatus   zCurrent status of this record)rO   choicesr$   r   z	Is ActiveTzWhether this record is activer,   c                   @   s   e Zd ZdZdS )zStatusModel.MetaTNr&   r   r   r   r   r   Z  s   r   c                 C   s    d| _ d| _| jddgd dS )zActivate this record.rj   Tstatus	is_activer:   Nrr   rs   r   rY   r   r   r   activate]  s    zStatusModel.activatec                 C   s    d| _ d| _| jddgd dS )zDeactivate this record.rk   Frr   rs   r:   Nrt   rY   r   r   r   
deactivatec  s    zStatusModel.deactivatec                 C   s    d| _ d| _| jddgd dS )zSuspend this record.rm   Frr   rs   r:   Nrt   rY   r   r   r   suspendi  s    zStatusModel.suspendc                 C   s    d| _ d| _| jddgd dS )zArchive this record.rn   Frr   rs   r:   Nrt   rY   r   r   r   archiveo  s    zStatusModel.archiveN)r
   r   r   r   r   ZSTATUS_CHOICESr   	CharFieldrr   rI   rs   r   ru   rv   rw   rx   r   r   r   r   ri   >  s0   




ri   c                   @   st   e Zd ZdZejedededdZejede	deddZ
G dd	 d	Zd
d Zdd Zdd ZdddZdS )MetaDataModelzAbstract model that provides metadata functionality.
    
    This model provides fields for storing additional metadata
    as JSON data.
    ZMetadataTz"Additional metadata stored as JSON)r$   r.   r   Tagsz Tags associated with this recordc                   @   s   e Zd ZdZdS )zMetaDataModel.MetaTNr&   r   r   r   r   r     s   r   c                 C   s(   || j kr$| j | | jdgd dS )zAdd a tag to this record.tagsr:   N)r|   appendr   r   tagr   r   r   add_tag  s    
zMetaDataModel.add_tagc                 C   s(   || j kr$| j | | jdgd dS )zRemove a tag from this record.r|   r:   N)r|   remover   r~   r   r   r   
remove_tag  s    
zMetaDataModel.remove_tagc                 C   s   || j |< | jdgd dS )zSet a metadata value.metadatar:   N)r   r   )r   keyvaluer   r   r   set_metadata  s    
zMetaDataModel.set_metadataNc                 C   s   | j ||S )zGet a metadata value.)r   get)r   r   r$   r   r   r   get_metadata  s    zMetaDataModel.get_metadata)N)r
   r   r   r   r   	JSONFieldr   dictr   listr|   r   r   r   r   r   r   r   r   r   rz   v  s$   rz   c                   @   s.   e Zd ZdZG dd dZdd Zdd ZdS )		BaseModela`  
    Abstract base model that provides common fields for all models.
    
    This model includes:    
    - UUID :: UUID primary key for better security
    - Timestamps :: Created and updated timestamps
    - Soft delete :: Soft delete functionality
    - Audit trail :: Created and updated by user tracking 
    - Common methods for all models 
    c                   @   s   e Zd ZdZdS )zBaseModel.MetaTNr&   r   r   r   r   r     s   r   c                 C   s   | j j d| j dS )z:Default string representation using the model name and ID.z ())r   r
   r*   rY   r   r   r   __str__  s    zBaseModel.__str__c                 C   sF   ddl m} | jj }z|| dd| jidW S    Y dS X dS )z
        Get the absolute URL for this model instance.
        
        This method should be overridden in child models to provide
        the correct URL for the model's detail view.
        r   )reversez-detailrX   )r   #N)django.urlsr   r   r
   lowerrX   )r   r   
model_namer   r   r   get_absolute_url  s    zBaseModel.get_absolute_urlN)r
   r   r   r   r   r   r   r   r   r   r   r     s   r   c                   @   s   e Zd ZdZG dd dZdS )FullBaseModela.  Complete base model with all functionality.
    
    This model combines all available base functionality:
    - UUID primary key
    - Timestamps
    - Soft delete
    - Audit trail
    - Status management
    - Metadata storage
    
    Use this for models that need comprehensive functionality.
    c                   @   s   e Zd ZdZdS )zFullBaseModel.MetaTNr&   r   r   r   r   r     s   r   N)r
   r   r   r   r   r   r   r   r   r     s   r   )r   r(   	django.dbr   django.utilsr   django.utils.translationr   r   Modelr   r"   r+   rM   r[   rf   ri   rz   r   r   r   r   r   r   <module>   s   %V-B18.#