U
    hO                     @   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mZmZ e 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dS )a!  
Adtlas Activities Serializers

This module contains the Django REST Framework serializers for the activities app,
providing comprehensive data serialization and validation for activity tracking,
category management, and analytics functionality.

Features:
    - Activity serialization with nested relationships
    - Category management serialization
    - Activity summary serialization
    - Custom validation and field handling
    - Optimized queries for performance

Author: Adtlas Development Team
Version: 1.0.0
Last Updated: 2025-01-27
    )timezone)serializers)get_user_model)gettext_lazy)ContentType)ActivityActivityCategoryActivitySummaryc                   @   s.   e Zd ZdZe ZG dd dZdd ZdS )UserBasicSerializerao  
    Basic user serializer for activity relationships.
    
    This serializer provides essential user information for
    activity records without exposing sensitive data.
    
    Fields:
        - id: User ID
        - email: User email address
        - first_name: User first name
        - last_name: User last name
        - full_name: Computed full name
    c                   @   s*   e Zd ZeZdddddgZddddgZdS )zUserBasicSerializer.Metaidemail
first_name	last_name	full_nameN)__name__
__module____qualname__Usermodelfieldsread_only_fields r   r   =/var/www/html/Focus/src/apps/activities/api/v1/serializers.pyMeta1   s   r   c                 C   s@   |j r|jr|j  d|j S |j r*|j S |jr6|jS |jS dS )z
        Get user's full name.
        
        Args:
            obj: User instance
        
        Returns:
            str: User's full name or email if name not available
         N)r   r   r   selfobjr   r   r   get_full_name6   s    
z!UserBasicSerializer.get_full_nameN)	r   r   r   __doc__r   SerializerMethodFieldr   r   r   r   r   r   r   r
       s   r
   c                   @   s>   e Zd ZdZe ZG dd dZdd Zdd Z	dd	 Z
d
S )ActivityCategorySerializera.  
    Serializer for activity categories.
    
    This serializer handles activity category data including
    validation, creation, and updates with proper field handling.
    
    Fields:
        - All ActivityCategory model fields
        - activity_count: Number of activities in this category
    c                
   @   s4   e Zd ZeZddddddddd	d
g
Zddd	d
gZdS )zActivityCategorySerializer.Metar   namecodedescriptioncoloricon	is_active
created_at
updated_atactivity_countN)r   r   r   r   r   r   r   r   r   r   r   r   X   s           r   c                 C   s   t |d|j S )z
        Get the number of activities in this category.
        
        Args:
            obj: ActivityCategory instance
        
        Returns:
            int: Number of activities in this category
        r*   )getattr
activitiescountr   r   r   r   get_activity_count`   s    
z-ActivityCategorySerializer.get_activity_countc                 C   sB   |r>t jj|d}| jr(|j| jjd}| r>tt	d|S )z
        Validate category code uniqueness.
        
        Args:
            value: Category code value
        
        Returns:
            str: Validated code value
        
        Raises:
            ValidationError: If code already exists
        )r#   )pkz)A category with this code already exists.)
r   objectsfilterinstanceexcluder/   existsr   ValidationError_)r   valuequerysetr   r   r   validate_codel   s    z(ActivityCategorySerializer.validate_codec                 C   s>   |r| dsttd|r:t|dkr:ttd|S )z
        Validate color format.
        
        Args:
            value: Color value
        
        Returns:
            str: Validated color value
        
        Raises:
            ValidationError: If color format is invalid
        #z,Color must be in hex format (e.g., #FF5733).)      z4Color must be in valid hex format (#RGB or #RRGGBB).)
startswithr   r5   r6   lenr   r7   r   r   r   validate_color   s    z)ActivityCategorySerializer.validate_colorN)r   r   r   r   r   r    r*   r   r.   r9   r@   r   r   r   r   r!   J   s   r!   c                   @   s   e Zd ZdZG dd dZdS )ContentTypeSerializeraK  
    Serializer for content types in activity relationships.
    
    This serializer provides content type information for
    activities that reference other model instances.
    
    Fields:
        - id: Content type ID
        - app_label: Application label
        - model: Model name
        - name: Human-readable name
    c                   @   s(   e Zd ZeZddddgZddddgZdS )zContentTypeSerializer.Metar   	app_labelr   r"   N)r   r   r   r   r   r   r   r   r   r   r   r      s   r   N)r   r   r   r   r   r   r   r   r   rA      s   rA   c                       s   e Zd ZdZeddZeddZeddZ	e
 Ze
 Ze
 Ze
jdddZG dd dZdd	 Zd
d Zdd Z fddZ  ZS )ActivitySerializera  
    Comprehensive serializer for activities.
    
    This serializer handles activity data with nested relationships,
    computed fields, and optimized queries for performance.
    
    Fields:
        - All Activity model fields
        - user: Nested user information
        - category: Nested category information
        - content_type: Nested content type information
        - object_display: Human-readable object representation
        - duration_display: Human-readable duration
        - time_ago: Relative time display
    T	read_onlyget_action_displaysourcerE   c                   @   sP   e Zd ZeZddddddddd	d
dddddddddgZddddd	ddddg	ZdS )zActivitySerializer.Metar   useractionaction_displaycategoryr$   content_type	object_idobject_display
ip_address
user_agentsession_keyis_successfulerror_messageduration_msduration_displaymetadatar(   time_agoN)r   r   r   r   r   r   r   r   r   r   r   r      s>                        r   c                 C   s   |  S )z
        Get human-readable representation of the related object.
        
        Args:
            obj: Activity instance
        
        Returns:
            str: Human-readable object representation
        get_object_displayr   r   r   r   rZ      s    
z%ActivitySerializer.get_object_displayc                 C   sn   |j dkrdS |j dk r$|j  dS |j dk r@|j d ddS |j d }|j d d }| d|ddS dS )z
        Get human-readable duration display.
        
        Args:
            obj: Activity instance
        
        Returns:
            str: Human-readable duration or None
        N  ms`  .1fsm rU   r   r   minutessecondsr   r   r   get_duration_display   s    




z'ActivitySerializer.get_duration_displayc                 C   s   ddl m} ||jt S )z
        Get relative time display for activity creation.
        
        Args:
            obj: Activity instance
        
        Returns:
            str: Relative time display
        r   )	timesince)django.utils.timesincerf   r(   r   now)r   r   rf   r   r   r   get_time_ago   s    
zActivitySerializer.get_time_agoc              	      sl   t  |}|jrdnd|d< |jrhz(t|jtrJddl}||j|d< W n |jt	fk
rf   Y nX |S )z
        Customize the serialized representation.
        
        Args:
            instance: Activity instance
        
        Returns:
            dict: Serialized data
        SuccessFailedsuccess_displayr   NrW   )
superto_representationrS   rW   
isinstancestrjsonloadsJSONDecodeError	TypeError)r   r2   datarq   	__class__r   r   rn   
  s    
z$ActivitySerializer.to_representation)r   r   r   r   r
   rI   r!   rL   rA   rM   r   r    rO   rV   rX   	CharFieldrK   r   rZ   re   ri   rn   __classcell__r   r   rv   r   rC      s   


rC   c                   @   sZ   e Zd ZdZejdddZejdddZG dd dZdd Z	d	d
 Z
dd Zdd ZdS )ActivityCreateSerializeraj  
    Serializer for creating new activities.
    
    This serializer handles activity creation with validation
    and automatic field population from request context.
    
    Fields:
        - Required: action, description
        - Optional: category, content_type, object_id, metadata
        - Auto-populated: user, ip_address, user_agent, session_key
    FT)required
allow_nullc                   @   s,   e Zd ZeZddddddddd	d
ddgZdS )zActivityCreateSerializer.MetarJ   r$   category_idcontent_type_idrN   rS   rT   rU   rW   rP   rQ   rR   Nr   r   r   r   r   r   r   r   r   r   r   7  s            r   c                 C   sH   |dk	rDzt jj|dd}|W S  t jk
rB   ttdY nX |S )a  
        Validate category exists and is active.
        
        Args:
            value: Category ID
        
        Returns:
            int: Validated category ID
        
        Raises:
            ValidationError: If category doesn't exist or is inactive
        NT)r   r'   z.Invalid category ID or category is not active.)r   r0   getDoesNotExistr   r5   r6   )r   r7   rL   r   r   r   validate_category_id?  s    
z-ActivityCreateSerializer.validate_category_idc                 C   sF   |dk	rBzt jj|d |W S  t jk
r@   ttdY nX |S )a  
        Validate content type exists.
        
        Args:
            value: Content type ID
        
        Returns:
            int: Validated content type ID
        
        Raises:
            ValidationError: If content type doesn't exist
        Nr   zInvalid content type ID.)r   r0   r   r   r   r5   r6   r?   r   r   r   validate_content_type_idV  s    
z1ActivityCreateSerializer.validate_content_type_idc                 C   sH   | dr"| ds"ttd| drD| dsDttd|S )z
        Perform cross-field validation.
        
        Args:
            attrs: Validated attributes
        
        Returns:
            dict: Validated attributes
        
        Raises:
            ValidationError: If validation fails
        r~   rN   z5object_id is required when content_type is specified.z5content_type is required when object_id is specified.)r   r   r5   r6   )r   attrsr   r   r   validatem  s    z!ActivityCreateSerializer.validatec                 C   sR   | dd}| dd}|r.tjj|d|d< |rDtjj|d|d< tjjf |S )z
        Create activity with proper field mapping.
        
        Args:
            validated_data: Validated data
        
        Returns:
            Activity: Created activity instance
        r}   Nr~   r   rL   rM   )popr   r0   r   r   r   create)r   validated_datar}   r~   r   r   r   r     s    zActivityCreateSerializer.createN)r   r   r   r   r   IntegerFieldr}   r~   r   r   r   r   r   r   r   r   r   rz   '  s   rz   c                   @   sR   e Zd ZdZeddZeddZe	 Z
e	 ZG dd dZdd Zdd	 Zd
S )ActivitySummarySerializera  
    Serializer for activity summaries.
    
    This serializer handles activity summary data with
    nested relationships and computed fields for analytics.
    
    Fields:
        - All ActivitySummary model fields
        - user: Nested user information
        - category: Nested category information
        - success_rate: Computed success rate
        - avg_duration_display: Human-readable average duration
    TrD   c                   @   s@   e Zd ZeZddddddddd	d
dddgZddddd
ddgZdS )zActivitySummarySerializer.Metar   daterI   rL   total_activitiessuccessful_activitiesfailed_activitiessuccess_rateavg_duration_msavg_duration_display
unique_ipsr(   r)   N)r   r   r   r	   r   r   r   r   r   r   r   r     s.                 r   c                 C   s   |j dkrdS |j|j  d S )z
        Calculate success rate percentage.
        
        Args:
            obj: ActivitySummary instance
        
        Returns:
            float: Success rate as percentage
        r   g        d   )r   r   r   r   r   r   get_success_rate  s    

z*ActivitySummarySerializer.get_success_ratec                 C   sr   |j dkrdS |j dk r&|j ddS |j dk rB|j d ddS |j d }|j d d }|dd|ddS dS )	z
        Get human-readable average duration display.
        
        Args:
            obj: ActivitySummary instance
        
        Returns:
            str: Human-readable duration or None
        Nr[   z.0fr\   r]   r^   r_   r`   )r   rb   r   r   r   get_avg_duration_display  s    




z2ActivitySummarySerializer.get_avg_duration_displayN)r   r   r   r   r
   rI   r!   rL   r   r    r   r   r   r   r   r   r   r   r   r     s   

r   c                   @   s*   e Zd ZdZeddZdd Zdd ZdS )	ActivityBulkCreateSerializerz
    Serializer for bulk activity creation.
    
    This serializer handles bulk creation of activities
    for batch processing and import operations.
    
    Fields:
        - activities: List of activity data
    T)manyc                 C   sv   |d }g }|D ]X}| dd}| dd}|rBtjj|d|d< |rXtjj|d|d< |tf | qtj|S )z
        Create multiple activities in bulk.
        
        Args:
            validated_data: Validated data with activities list
        
        Returns:
            list: List of created activity instances
        r,   r}   Nr~   r   rL   rM   )r   r   r0   r   r   appendr   bulk_create)r   r   Zactivities_datar,   activity_datar}   r~   r   r   r   r     s    
z#ActivityBulkCreateSerializer.createc                 C   s0   |st tdt|dkr,t td|S )z
        Validate activities list.
        
        Args:
            value: List of activity data
        
        Returns:
            list: Validated activities data
        
        Raises:
            ValidationError: If validation fails
        z"At least one activity is required.r   z/Cannot create more than 100 activities at once.)r   r5   r6   r>   r?   r   r   r   validate_activities  s    z0ActivityBulkCreateSerializer.validate_activitiesN)r   r   r   r   rz   r,   r   r   r   r   r   r   r     s   

r   c                   @   s   e Zd ZdZejdddZe ZejdddZ	ejdddZ
e ZejdddZe Ze ZG dd	 d	Zd
d Zdd Zdd Zdd ZdS )ActivityExportSerializerz
    Serializer for activity export operations.
    
    This serializer provides a flattened representation
    of activities suitable for CSV/Excel export.
    
    Fields:
        - Flattened activity data with related object information
    z
user.emailTrG   zcategory.namezcontent_type.namerF   c                   @   s6   e Zd ZeZddddddddd	d
dddddddgZdS )zActivityExportSerializer.Metar   
user_email	user_namerJ   rK   category_namer$   content_type_namerN   rO   rP   rS   rl   rU   rV   rT   r(   Nr   r   r   r   r   r   =  s&                r   c                 C   s\   |j s
dS |j jr0|j jr0|j j d|j j S |j jr@|j jS |j jrP|j jS |j jS dS )z
        Get user's full name for export.
        
        Args:
            obj: Activity instance
        
        Returns:
            str: User's full name or email
        	Anonymousr   N)rI   r   r   r   r   r   r   r   get_user_nameF  s    
z&ActivityExportSerializer.get_user_namec                 C   s   |  S )z
        Get object display for export.
        
        Args:
            obj: Activity instance
        
        Returns:
            str: Object display string
        rY   r   r   r   r   rZ   \  s    
z+ActivityExportSerializer.get_object_displayc                 C   s   |j r
dS dS )z
        Get success status display for export.
        
        Args:
            obj: Activity instance
        
        Returns:
            str: Success status display
        rj   rk   )rS   r   r   r   r   get_success_displayh  s    
z,ActivityExportSerializer.get_success_displayc                 C   sn   |j dkrdS |j dk r$|j  dS |j dk r@|j d ddS |j d }|j d d }| d|ddS dS )	z
        Get duration display for export.
        
        Args:
            obj: Activity instance
        
        Returns:
            str: Duration display
        N r[   r\   r]   r^   r_   r`   ra   rb   r   r   r   re   t  s    




z-ActivityExportSerializer.get_duration_displayN)r   r   r   r   r   rx   r   r    r   r   r   rO   rK   rl   rV   r   r   rZ   r   re   r   r   r   r   r   )  s   
	r   N)r   django.utilsr   rest_frameworkr   django.contrib.authr   django.utils.translationr   r6   "django.contrib.contenttypes.modelsr   apps.activities.modelsr   r   r	   r   ModelSerializerr
   r!   rA   rC   rz   r   
Serializerr   r   r   r   r   r   <module>   s   *VsxFD