
    e2i                     j    S SK Jr  SSKJr  S SKJr  S SKJr  S rS r	 " S S	\R                  5      rg
)    )serializers   )Project)Sum)Stampc                    U (       d  g[        U 5      R                  SS5      R                  5       n SU ;   aW  U R                  S5      n[	        U5      S:  a7   [        US   5      =(       d    Sn[        US   5      =(       d    SnUS-  U-   $  [        U 5      n[        US-  5      $ ! [        [        4 a     N,f = f! [         a     gf = f)z9Parse duration string (HH:MM or decimal) to total minutesr   hrs :   r   <   )	strreplacestripsplitlenint
ValueError
IndexErrorfloat)duration_strpartshoursminutesdecimal_hourss        %D:\TimeStamps\projects\serializers.pyparse_duration_to_minutesr      s    |$,,UB7==?L
l""3'u:?E!H*eAh-,1
g--l+=2%&& 
+   s$   5B) B? )B<;B<?
CCc                 6    U S:X  a  gU S-  nU S-  nUS SUS 3$ )z$Format total minutes to HH:MM stringr   z00:00r   02dr    )total_minutesr   r   s      r   format_minutes_to_durationr"      s6    REb GC['#''    c                   2  ^  \ rS rSr\R
                  " SSS9r\R                  " 5       r\R                  " 5       r	\R                  " 5       r
\R                  " 5       r\R                  " 5       r " S S5      rS rS rS	 rS
 rS rU 4S jrU 4S jrSrU =r$ )ProjectSerializer%   FT)required
allow_nullc                   (    \ rS rSr\r/ SQr/ SQrSrg)ProjectSerializer.Meta.   )idnamecodeestimated_timesum_tasks_estimatesdue_dateclient	is_public
created_at
updated_attotal_hours_spentvariancestatus_indicatorlast_activity_dateactive_users_count)r,   r4   r5   r    N)	__name__
__module____qualname____firstlineno__r   modelfieldsread_only_fields__static_attributes__r    r#   r   Metar*   .   s    
 >r#   rC   c                     [         R                  R                  UR                  S9nSnU H.  nUR                  (       d  M  U[        UR                  5      -  nM0     [        U5      $ )z&Calculate total hours spent on project
project_idr   )r   objectsfilterr,   durationr   r"   )selfobjstampsr!   stamps        r   get_total_hours_spent'ProjectSerializer.get_total_hours_spent8   sV    %%%8E~~~!:5>>!JJ  *-88r#   c                    [         R                  R                  UR                  S9nSnU H.  nUR                  (       d  M  U[        UR                  5      -  nM0     UR                  (       a  [        UR                  5      OSnX5-
  nUS:X  a  [        [        U5      5      SUS:  S.$ X5-  S-  n[        [        U5      5      [        US5      US:  S.$ )z5Calculate variance between estimated and actual hoursrE   r   )	formatted
percentageis_overd   r   )
r   rG   rH   r,   rI   r   r/   r"   absround)rJ   rK   rL   r!   rM   estimated_minutesvariance_minutesvariance_percentages           r   get_varianceProjectSerializer.get_varianceA   s    %%%8E~~~!:5>>!JJ  NQM_M_5c6H6HIef(<!7<L8MN+a/   -@3F3C8H4IJ 3Q7'!+
 	
r#   c                 d   [         R                  R                  UR                  S9nSnU H.  nUR                  (       d  M  U[        UR                  5      -  nM0     UR                  (       a  [        UR                  5      OSnUS:X  a  gUS:  a  X5-  S-  OSnUS:  a  gUS:  a  gUS	:  a  g
g)zGet project status indicatorrE   r   	no_budgetrT   x   over_budgetn   at_riskP   under_budgeton_track)r   rG   rH   r,   rI   r   r/   )rJ   rK   rL   r!   rM   rW   rY   s          r   get_status_indicator&ProjectSerializer.get_status_indicatorZ   s    %%%8E~~~!:5>>!JJ  NQM_M_5c6H6HIef!K\_`K`}@3Ffg$  3& 2%!r#   c                     [         R                  R                  UR                  S9R	                  SS5      R                  5       nU(       a  UR                  R                  5       $ S$ )zGet last activity daterE   z-datez-timeN)r   rG   rH   r,   order_byfirstdate	isoformat)rJ   rK   
last_stamps      r   get_last_activity_date(ProjectSerializer.get_last_activity_dater   sM    ]]))SVV)<EEgwW]]_
.8z((*BdBr#   c                    SSK Jn  SSKJn  UR	                  5       R                  5       U" SS9-
  n[        R                  R                  UR                  US9R                  SSS	9R                  5       n[        [        U5      5      $ )
z2Get count of active users (stamps in last 30 days)r   )timezone)	timedelta   )days)rF   	date__gteuser_idT)flat)django.utilsrp   datetimerq   nowrj   r   rG   rH   r,   values_listdistinctr   set)rJ   rK   rp   rq   thirty_days_agoactive_user_idss         r   get_active_users_count(ProjectSerializer.get_active_users_countw   st    )&",,.--/)2DD--..vv% / 
 +id+
+HHJ 	 3'((r#   c                    > [         TU ]  U5      nUR                  S5      (       d   UR                  (       a  UR                  US'   U$ )z/Map end_date to due_date if due_date is not setr1   )superto_representationgetend_date)rJ   instanceret	__class__s      r   r   #ProjectSerializer.to_representation   s=    g'1wwz""x'8'8&//C
O
r#   c                 ^   > SU;   a  US   (       a  SU;  a  US   US'   [         TU ]  U5      $ )z#Map due_date to end_date for savingr1   r   )r   to_internal_value)rJ   datar   s     r   r   #ProjectSerializer.to_internal_value   s9    $z"2%#'
#3Z w(..r#   r    )r;   r<   r=   r>   r   	DateFieldr1   SerializerMethodFieldr6   r7   r8   r9   r:   rC   rN   rZ   re   rm   r   r   r   rB   __classcell__)r   s   @r   r%   r%   %   s    $$eEH#99;002H"88:$::<$::<> >9
20C
	)/ /r#   r%   N)rest_frameworkr   modelsr   django.db.modelsr   stamps.modelsr   r   r"   ModelSerializerr%   r    r#   r   <module>r      s/    &    .(j/33 j/r#   