
    vg                        d dl mZm Z mZ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mZ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 d dlmZ d dlmZm Z m!Z! d dl" d dl"m#Z# d dl$m%Z%m&Z&m'Z' d dl( d dl)m*Z* d dl+m,Z,m-Z- d dl.m/Z/ d dl0m1Z1 ddl2m3Z3m4Z4 ddl5m6Z6m7Z7 ddl8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z> d Z? G d de      Z@ G d de      ZA G d de      ZB G d  d!e      ZC G d" d#e      ZD G d$ d%e      ZE G d& d'e      ZF G d( d)e      ZG G d* d+e      ZH G d, d-e      ZI G d. d/e      ZJ G d0 d1e      ZK G d2 d3e      ZL G d4 d5e      ZM G d6 d7e      ZN G d8 d9e      ZO G d: d;e      ZP G d< d=e      ZQy>)?    )datedatetime	timedeltatimezone)template)settings)EmailMessage)Case	CharFieldFValueWhen)	QueryDict)get_object_or_404)method_decorator)PageNumberPagination)IsAuthenticated)Response)APIView)
AttendanceAttendanceActivityEmployeeShiftDay)*)	clock_out)find_expected_attendancesfind_late_comefind_on_time)ConfiguredEmailBackend)generate_pdfis_reportingmanager)EmployeeFilter)RecruitmentMailTemplate   )manager_permission_requiredpermission_required)groupby_querysetpermission_based_queryset)AttendanceActivitySerializer$AttendanceLateComeEarlyOutSerializerAttendanceOverTimeSerializerAttendanceRequestSerializerAttendanceSerializerMailTemplateSerializerc                     t        dd      }| j                         D ]B  \  }}t        |t              r|D ]  }|j	                  ||        0|j                  ||i       D |S )N T)mutable)r   items
isinstancelist
appendlistupdate)data
query_dictkeyvalueitems        :/var/www/horilla/horilla_api/api_views/attendance/views.pyr7   r7   .   sl    2t,Jjjl ,
UeT" 1%%c401 sEl+,     c                       e Zd ZdZegZd Zy)ClockInAPIViewz
    Allows authenticated employees to clock in, determining the correct shift and attendance date, including handling night shifts.

    Methods:
        post(request): Processes and records the clock-in time.
    c                    t        |      \  }}t        j                         }|j                  j	                  d      r|j                  }|r||j
                  }t        j                         }|j                  j	                  d      r|j                  }|}|j                  d      j                         }t        j                  j	                  |      }t        j                         j                  d      }	|j                  j	                  d      r|j                  j                  d      }	t        |	      }
t        d      }t        ||      \  }}}||kD  rh||
kD  rc|t        d	
      z
  }|j                  d      j                         }t        j                  j	                  |      }t        ||      \  }}}|}|}t!        |||||	|||||
       t#        ddid      S t#        ddi      S )Nr   r   %A)dayz%H:%Mtimez12:00)rA   shift   )days)
employee
date_todayattendance_daterA   nowrC   minimum_hour
start_timeend_timein_datetimemessagez
Clocked-In   statuserrorzOYou Don't have work information filled or your employee detail neither entered )employee_existsr   rI   __dict__getshift_idr   todaystrftimelowerr   objectsrB   strtime_secondsshift_schedule_todayr    clock_in_attendance_and_activityr   )selfrequestrF   	work_infodatetime_nowrC   rG   rH   rA   rI   now_secmid_day_secrJ   start_time_secend_time_secdate_yesterdayday_yesterdays                    r;   postzClockInAPIView.postC   s   -g6)||~
+"++L	-&&EJ##F+$\\
(O%%d+113C"**..3.7C,,.))'2C##F+ll++G4%c*G)'2K9Mu:6L., , ( &0)2C%CN$2$;$;D$A$G$G$IM$4$<$<$@$@]$@$SMAU)B>L., '5O'C,!% /))%( Y5cBBj
 	
r<   N__name__
__module____qualname____doc__r   permission_classesrh    r<   r;   r>   r>   9   s     **7
r<   r>   c                       e Zd ZdZegZd Zy)ClockOutAPIViewz
    Allows authenticated employees to clock out, updating the latest attendance record and handling early outs.

    Methods:
        post(request): Records the clock-out time.
    c                 p   t        j                         }t        j                         j	                         }t        j                         }	 t        t        |j                  |||             t        ddid      S # t        $ r }t        j                  d|       Y d }~nd }~ww xY wt        ddid      S )N)userr   rB   r   rN   zClocked-OutrO   rP   zGot an error in clock_out)r   rW   r   rI   rB   r   Requestrs   r   	ExceptionloggerrR   )r^   r_   current_datecurrent_timecurrent_datetimerR   s         r;   rh   zClockOutAPIView.post   s    zz|||~**,#<<>	= %%-	 Y6sCC 	=LL4e<<	=M23??s   0A= =	B&B!!B&Nri   ro   r<   r;   rq   rq   }   s     **@r<   rq   c                       e Zd ZdZegZeZd ZddZ	 e
d      d        Z e ed            d        Z e ed	            d
        Zy)AttendanceViewa  
    Handles CRUD operations for attendance records.

    Methods:
        get_queryset(request, type): Returns filtered attendance records.
        get(request, pk=None, type=None): Retrieves a specific record or a list of records.
        post(request): Creates a new attendance record.
        put(request, pk): Updates an existing attendance record.
        delete(request, pk): Deletes an attendance record and adjusts related overtime if needed.
    c                    |dk(  rbt         j                  j                         }t        d      }|t        |j                        }t
        j                  j                  |d      }nj|dk(  r!t
        j                  j                  d      }nD|dk(  r!t
        j                  j                  d      }nt
        j                  j                         }|j                  }d	}t        ||d
      }|S )Notz00:30T)overtime_second__gteattendance_validated	validatedr   znon-validatedFattendance.view_attendance)user_obj)
AttendanceValidationConditionrZ   firstr[   minimum_overtime_to_approver   filterallrs   r'   )r^   r_   type	conditionminotquerysetrs   perms           r;   get_querysetzAttendanceView.get_queryset   s    4<5==CCEI#G,E$'	(M(MN%--44).)- 5 
 [ !))00d0KH_$!))00e0LH!))--/H||+,T4DQr<   Nc                    |r4t        t        |      }t        |      }t        |j                  d      S | j                  ||      }| j                  |j                  |      j                  }|j                  j                  dd       }|r|j                         }	t        ||	||      S t               }
|
j                  ||      }t        |d      }|
j                  |j                        S )	NpkinstancerO   rP   )r   groupby_fieldTmany)r   r   r,   r   r6   r   filterset_classGETqsrU   build_absolute_urir&   r   paginate_querysetget_paginated_response)r^   r_   r   r   
attendance
serializerattendancesattendances_filter_queryset
field_nameurl	paginaterpages               r;   rU   zAttendanceView.get   s    *:"=J-zBJJOOC88''6&*&:&:KK+ '; '

" 	$ [[___d;
,,.C#j*E  )*	**+FP)$T:
//
@@r<   zattendance.add_attendancec                    t        |j                        }|j                         r'|j                          t	        |j                  d      S |j                  j                  d      }|j                  j                  dt        j                               }t        j                  j                  ||      j                         rt	        ddgid	      S t	        |j                  d	      S )
Nr6   rO   rP   employee_idrH   r   rH   rR   @Attendance for this employee on the current date already exists.  )r,   r6   is_validsaver   rU   r   rW   r   rZ   r   existserrorsr^   r_   r   r   rH   s        r;   rh   zAttendanceView.post   s    )w||<
 OOJOOC88ll&&}5!,,**+<djjlK$$#_ % 

&( Z
   
))#66r<   attendance.change_attendancec                    	 t         j                  j                  |      }t        ||j                        }|j                         r'|j                          t	        |j                  d      S |j                  }d|j                  v rd	}||j                  d   v rdd
gi}t	        |d      S # t         j                  $ r t	        ddid      cY S w xY w)NiddetailzAttendance record not found.  rP   r   r6   rO   non_field_errorsz?The fields employee_id, attendance_date must make a unique set.z1The employee already has attendance on this date.r   )
r   rZ   rU   DoesNotExistr   r,   r6   r   r   r   )r^   r_   r   r   r   serializer_errorsunique_error_msgs          r;   putzAttendanceView.put   s    	T#++//2/6J *:GLLQ
 OOJOOC88 '--!2!22Q   :#4#45G#HH&K)%!
 )#66+ && 	TX'EFsSS	Ts    B/ /"CCzattendance.delete_attendancec                    t         j                  j                  |      }|j                  }|j	                  d      j                         }|j                  j                  j                  |      j                         }||j                  rZt        |j                        }t        |j                        }||kD  r||z
  }n||z
  }t        |      |_        |j                          	 |j!                          t#        ddhd      S 	 |j!                          t#        ddhd      S # t$        $ r}t#        d| hd	      cY d }~S d }~ww xY w# t$        $ r}t#        d| hd	      cY d }~S d }~ww xY w)
Nr   z%B)monthrQ   deletedrO   rP   zerror:r   )r   rZ   rU   rH   rX   rY   r   employee_overtimer   lastattendance_overtime_approver[   overtimeattendance_overtimeformat_timer   deleter   ru   )	r^   r_   r   r   r   r   total_overtimeattendance_overtime_secondsrR   s	            r;   r   zAttendanceView.delete  se   ''++r+2
**t$**,));;BBBOTTV55!01B1B!C.=22/+ "$??%36Q%QN%@>%QN$/$?!D!!#9 5cBBD!!#9 5cBB  DeW 6sCCD  DeW 6sCCDs<   )D( 	E (	E1E EE	E1E,&E1,E1)NN)rj   rk   rl   rm   r   rn   AttendanceFiltersr   r   rU   r$   rh   r   r%   r   r   ro   r<   r;   r{   r{      s    	 **'O0A0 !!<=7 >7( )*HIJ7 K74 )*HIJD KDr<   r{   c                       e Zd ZdZd Zy)ValidateAttendanceViewz
    Validates an attendance record and sends a notification to the employee.

    Method:
        put(request, pk): Marks the attendance as validated and notifies the employee.
    c                    t         j                  j                  |      j                  d      }t         j                  j                  |      j	                         }	 t
        j                  |j                  j                  |j                  j                  d|j                   dd|j                   d|j                   dd	|j                   d
d|j                   dddd|j                   
       t        d      S #  Y xY w)Nr   Tr   zYour attendance for the date z is validatedu+   تم تحقيق حضورك في تاريخ u!   Deine Anwesenheit für das Datum u    ist bestätigt.z&Se valida tu asistencia para la fecha .u   Votre présence pour la date u    est validée.z/attendance/view-my-attendance	checkmarkz&/api/attendance/attendance?employee_id		recipientverbverb_arverb_deverb_esverb_frredirecticonapi_redirectrO   rP   )r   rZ   r   r5   r   notifysendrs   employee_getr   employee_user_idrH   r   r^   r_   r   r   s       r;   r   zValidateAttendanceView.put4  s   ''..".5<<RV<W
''..".5;;=
	KK))$00AA4Z5O5O4PP]^EjF`F`Eab;J<V<V;WWgh@A[A[@\\]^7
8R8R7SSab9 EjF\F\E]^   s##	s    BD D	Nrj   rk   rl   rm   r   ro   r<   r;   r   r   ,  s    $r<   r   c                       e Zd ZdZd Zy)OvertimeApproveViewz
    Approves overtime for an attendance record and sends a notification to the employee.

    Method:
        put(request, pk): Marks the overtime as approved and notifies the employee.
    c                 ^   	 t         j                  j                  |      j                  d      }t         j                  j                  |      j                         }	 t        j                  |j                  j                  |j                  j                  d|j                   dd	|j                   d
d|j                   dd|j                   d
d|j                   dddd
       t        d      S # t        $ r"}t        dt        |      id      cY d }~S d }~ww xY w#  Y >xY w)Nr   T)r   rR   r   rP   zYour z 's attendance overtime approved.u^   تمت الموافقة على إضافة ساعات العمل الإضافية لتاريخ r   u   Die Überstunden für den z wurden genehmigt.z5Se ha aprobado el tiempo extra de asistencia para el u)   Les heures supplémentaires pour la date u    ont été approuvées.z$/attendance/attendance-overtime-viewr   z(/api/attendance/attendance-hour-account/r   rO   )r   rZ   r   r5   ru   r   strr   r   r   rs   r   r   r   rH   r^   r_   r   r   Es        r;   r   zOvertimeApproveView.putQ  sN   	;#++22b29@@,0 A J  ''..".5;;=
	KK))$00AAZ7788XYx  zD  zT  zT  yU  UV  W4Z5O5O4PPbcOPZPjPjOkklmCJD^D^C__vw? G   s##'  	;Wc!f-c::	;"	s*   0C: !BD( :	D%D D% D%(D,Nr   ro   r<   r;   r   r   I  s    $r<   r   c                   D    e Zd ZdZeZegZddZd Z	 e
d      d        Zy)AttendanceRequestViewaJ  
    Handles requests for creating, updating, and viewing attendance records.

    Methods:
        get(request, pk=None): Retrieves a specific attendance request by `pk` or a filtered list of requests.
        post(request): Creates a new attendance request.
        put(request, pk): Updates an existing attendance request.
    Nc                    |rCt         j                  j                  |      }t        |      }t	        |j
                  d      S t         j                  j                  d      }t        |d|      }|t         j                  j                  |j                  d	      z  }t        |j                  |      j                  }|j                  j                  d
d       }|r|j                         }t        ||||      S t               }	|	j                  ||      }
| j!                  |
d      }|	j#                  |j
                        S )Nr   r   rO   rP   T)is_validate_requestr   )r_   r   r   )employee_id__employee_user_idr   r   r   )r   rZ   rU   r+   r   r6   r   filtersubordinatesrs   r   r   r   r   r&   r   r   serializer_classr   )r^   r_   r   r   r   requestsrequest_filtered_querysetr   r   
pagenationr   s              r;   rU   zAttendanceRequestView.gety  s/   #++//2/6J4jIJJOOC88%%,, $ - 
 &-

 j0077*1,, $ 8 
 
 %6gkk8$L$O$O![[___d;
,,.C#GS*>WXX)+
++,EwO**4d*;
00AAr<   c                    t        |j                        }|j                         r'|j                          t	        |j                  d      S |j                  j                  d      }|j                  j                  dt        j                               }t        j                  j                  ||      j                         rt	        ddgid	      S t	        |j                  d
      S )Nr   rO   rP   r   rH   r   rR   r   r   r   )r+   r6   r   r   r   rU   r   rW   r   rZ   r   r   r   r   s        r;   rh   zAttendanceRequestView.post  s    0gllC
 OOJOOC88ll&&}5!,,**+<djjlK$$#_ % 

&( Z
   
))#66r<   zattendance.update_attendancec                 L   t         j                  j                  |      }t        ||j                        }|j                         r|j                         }|j                  |_        |j                  |_        |j                  dk7  rQt        j                  |j                               |_        |j                  |_        d|_        |j                          nd|_        d|_        |j                          t#        |j                  d      S t#        |j$                  d      S )	Nr   r   create_requestTFrO   rP   r   )r   rZ   rU   r+   r6   r   r   r   r   request_typejsondumps	serializerequested_datarequest_descriptionr   is_validate_request_approvedr   r   )r^   r_   r   r   r   r   s         r;   r   zAttendanceRequestView.put  s    ''++r+2
0*7<<X
 !(H#-#9#9H $--HK&&*::,0JJx7I7I7K,L
)191M1M
.15
.!8=5/3,JOOC88
))#66r<   N)rj   rk   rl   rm   r+   r   r   rn   rU   rh   r$   r   ro   r<   r;   r   r   l  s>     3)*B<7( !!?@7 A7r<   r   c                   ,    e Zd ZdZ ed      d        Zy)AttendanceRequestApproveViewz
    Approves and updates an attendance request.

    Method:
        put(request, pk): Approves the attendance request, updates attendance records, and handles related activities.
    r   c                 h   	 t         j                  j                  |      }|j                  }|j                  }|j
                  }d|_        d|_        d|_        d |_	        |j                          |j                  t        j                  |j                        }|d   dk(  rd n|d   |d<   |d   dk(  rd n|d   |d<   t        j                  j                  |      j                  di | t         j                  j                  |      }|j                          |j                   |j"                  d|_        t$        j                  j                  |j&                  |||      }|r>|j                  |j&                  |j                  |j                  |j
                         nKt$        j                  j)                  |j&                  |j                  |j                  |j
                         t-        ddid
      S # t*        $ r"}	t-        dt/        |	      id	
      cY d }	~	S d }	~	ww xY w)Nr   TFattendance_clock_outNoneattendance_clock_out_date)r   rH   clock_in_dateclock_inrR   r   rP   rQ   approvedrO   ro   )r   rZ   rU   rH   attendance_clock_in_dateattendance_clock_inr   r   r   r   r   r   r   loadsr   r5   r   r   r   r   createru   r   r   )
r^   r_   r   r   prev_attendance_dateprev_attendance_clock_in_dateprev_attendance_clock_inr   activityr   s
             r;   r   z AttendanceRequestApproveView.put  s,   5	;#++//2/6J#-#=#= ,6,O,O)'1'E'E$.2J+6:J3-2J*-1J*OO((4!%J,E,E!F &&<=G '(>? 56 &&ABfL '(CD :;
 ""))R)077I.I'//33r3:
!//777?26
/-55<< * 6 6$8"?5	 =  OO$.$:$:(2(B(B&0&I&I!+!?!?	 $  '..55$.$:$:(2(B(B&0&I&I!+!?!?	 6  :.s;;  	;Wc!f-c::	;s   G5H 	H1H,&H1,H1N)rj   rk   rl   rm   r$   r   ro   r<   r;   r   r     s"     !!?@7< A7<r<   r   c                       e Zd ZdZd Zy)AttendanceRequestCancelViewz
    Cancels an attendance request.

    Method:
        put(request, pk): Cancels the attendance request, resetting its status and data, and deletes the request if it was a create request.
    c                    	 t         j                  j                  |      }|j                  j                  |j
                  k(  s&t        |      s|j
                  j                  d      rRd|_        d|_	        d |_
        d |_        d |_        |j                          |j                  dk(  r|j                          t!        dd	id
      S # t        $ r"}t!        dt#        |      id      cY d }~S d }~ww xY w)Nr   r   Fr   rR   r   rP   rQ   successrO   )r   rZ   rU   r   r   rs   r    has_permr   r   r   r   r   r   r   ru   r   r   r   s        r;   r   zAttendanceRequestCancelView.put  s    	;#++//2/6J&&777<<G&w/<<(()GH:?
716
.15
.,0
)*.
'!**.>>%%' 9-c::  	;Wc!f-c::	;s   B;C 	C7C2,C72C7Nr   ro   r<   r;   r  r    s    ;r<   r  c                   ~    e Zd ZdZegZd
dZ ed      d        Z ed      d        Z	 e
 ed            d	        Zy)AttendanceOverTimeViewa~  
    Manages CRUD operations for attendance overtime records.

    Methods:
        get(request, pk=None): Retrieves a specific overtime record by `pk` or a list of records with filtering and pagination.
        post(request): Creates a new overtime record.
        put(request, pk): Updates an existing overtime record.
        delete(request, pk): Deletes an overtime record.
    Nc                 
   |r3t        t        |      }t        |      }t        |j                  d      S t        |j                        }|j                  }|j                  |j                        }t        ||d      }||z  }|j                  j                  dd       }	|	r|j                         }
t        ||
|	|      S t               }|j                  ||      }t        |d      }|j!                  |j                        S )	Nr   rO   rP   )r   z"attendance.view_attendanceovertimer   Tr   )r   AttendanceOverTimer*   r   r6   AttendanceOverTimeFilterr   r   r   rs   r   rU   r   r&   r   r   r   )r^   r_   r   attendance_otr   r   r   self_accountr'   r   r   r   r   s                r;   rU   zAttendanceOverTimeView.get/  s    -.@RHM5mDJJOOC8827;;?"%%W\\R$6XC%
! -|;[[___d;
,,.C#GS*hGG)+
++Hg>1$TB
00AAr<   z!attendance.add_attendanceovertimec                     t        |j                        }|j                         r'|j                          t	        |j                  d      S t	        |j
                  d      S )Nr   rO   rP   r   )r*   r6   r   r   r   r   )r^   r_   r   s      r;   rh   zAttendanceOverTimeView.postG  sJ    1w||D
 OOJOOC88
))#66r<   z$attendance.change_attendanceovertimec                     t        t        |      }t        ||j                        }|j	                         r'|j                          t        |j                  d      S t        |j                  d      S )Nr   r   rO   rP   r   )r   r  r*   r6   r   r   r   r   )r^   r_   r   r  r   s        r;   r   zAttendanceOverTimeView.putO  s^    )*<D1"

  OOJOOC88
))#66r<   z$attendance.delete_attendanceovertimec                 b    t        t        |      }|j                          t        ddid      S )Nr   rN   zOvertime deleted successfully   rP   )r   r  r   r   r   s       r;   r   zAttendanceOverTimeView.deleteZ  s.    &'9bA
$CDSQQr<   r   )rj   rk   rl   rm   r   rn   rU   r$   rh   r   r   r%   r   ro   r<   r;   r  r  "  sq     **B0 !!DE7 F7 !!GH7 I7 )*PQRR SRr<   r  c                   &    e Zd ZdZegZddZddZy)LateComeEarlyOutViewa  
    Handles retrieval and deletion of late come and early out records.

    Methods:
        get(request, pk=None): Retrieves a list of late come and early out records with filtering.
        delete(request, pk=None): Deletes a specific late come or early out record by `pk`.
    Nc                     t        |j                        }t        |j                  d      }t	        |j
                  d      S NTr   rO   rP   )LateComeEarlyOutFilterr   r)   r   r   r6   r^   r_   r   r6   r   s        r;   rU   zLateComeEarlyOutView.getm  s1    %gkk29$''M

44r<   c                 b    t        t        |      }|j                          t        ddid      S )Nr   rN   zAttendance deleted successfullyr  rP   )r   AttendanceLateComeEarlyOutr   r   r   s       r;   r   zLateComeEarlyOutView.deleter  s.    &'AbI
$EFsSSr<   r   )rj   rk   rl   rm   r   rn   rU   r   ro   r<   r;   r  r  b  s     **5
Tr<   r  c                       e Zd ZdZddZy)AttendanceActivityViewz
    Retrieves attendance activity records.

    Method:
        get(request, pk=None): Retrieves a list of all attendance activity records.
    Nc                     t         j                  j                         }t        |d      }t	        |j
                  d      S r  )r   rZ   r   r(   r   r6   r  s        r;   rU   zAttendanceActivityView.get  s3    !))--/1$TB

44r<   r   rj   rk   rl   rm   rU   ro   r<   r;   r#  r#  x  s    5r<   r#  c                       e Zd ZdZd Zy)TodayAttendancez
    Provides the ratio of marked attendances to expected attendances for the current day.

    Method:
        get(request): Calculates and returns the attendance ratio for today.
    c                    t        j                         }|j                  d      j                         }t	        |||      }t        |      }t        |      }||z   }t        |      }d}	|dk7  r
||z  dz  d}	t        d|	id	
      S )Nr@   )rW   week_day)
start_date)r)  r   d   z.2fmarked_attendances_ratiorO   rP   )	r   rW   rX   rY   r   r   lenr   r   )
r^   r_   rW   r)  on_time	late_comelate_come_objmarked_attendancesexpected_attendancesr,  s
             r;   rU   zTodayAttendance.get  s     >>$'--/wehG"e4	I*W48(K#$ 1$&)==DSI % ')AB3
 	
r<   Nr%  ro   r<   r;   r'  r'    s    
r<   r'  c                       e Zd ZdZd Zy)OfflineEmployeesCountViewz
    Retrieves the count of active employees who have not clocked in today.

    Method:
        get(request): Returns the number of active employees who are not yet clocked in.
    c                     t        dt        j                         i      j                  j	                  d      j                  d      j                         }t        d|id      S )N
not_in_yetTemployee_work_info__isnull	is_activecountrO   rP   )r!   r   rW   r   excluder   r;  r   )r^   r_   r;  s      r;   rU   zOfflineEmployeesCountView.get  sQ    L$**,78R48VdV#UW	 	 %(55r<   Nr%  ro   r<   r;   r4  r4    s    6r<   r4  c                       e Zd ZdZd Zd Zy)OfflineEmployeesListViewz
    Lists active employees who have not clocked in today, including their leave status.

    Method:
        get(request): Retrieves and paginates a list of employees not clocked in today with their leave status.
    c                    t        dt        j                         i      j                  j	                  d      j                  d      }| j                  |      }t               }|j                  ||      }|j                  |      S )Nr6  Tr7  r9  )
r!   r   rW   r   r<  r   get_leave_statusr   r   r   )r^   r_   r   leave_statusr   r   s         r;   rU   zOfflineEmployeesListView.get  ss    L$**,78R48VdV# 	
 ,,X6)+
++L'B0066r<   c                    t        j                         }|j                         }|j                  t	        t        ||dt        d            t        ||dt        d            t        ||t        d            t        |t        d      	      t        d
      t                     t        d            j                  dddddd      }|D ]!  }|d   s	t        j                  |d   z   |d<   # |S )Nr  zOn Leave)leaverequest__start_date__lteleaverequest__end_date__gteleaverequest__statusthen	requestedzWaiting ApprovalzCanceled / Rejected)rC  rD  rF  Working)%employee_attendances__attendance_daterF  zExpected working)defaultoutput_field#employee_work_info__job_position_id)rA  job_position_idemployee_first_nameemployee_last_namerA  employee_profiler   rM  )r   rW   distinctannotater
   r   r   r   r   valuesr   	MEDIA_URL)r^   r   rW   employees_with_leave_statusrF   s        r;   r@  z)OfflineEmployeesListView.get_leave_status  s   

$$&&.&7&72705)3z*	 2705)412	 270545
 :?eIFV 01&[/2 CD5 '8 '
6 &! 
7 	$H 4 	H*+&&2D)EE +,	 +*r<   N)rj   rk   rl   rm   rU   r@  ro   r<   r;   r>  r>    s    	7/+r<   r>  c                   ,    e Zd ZdZegZed        Zd Zy)CheckingStatusz
    Checks and provides the current attendance status for the authenticated user.

    Method:
        get(request): Returns the attendance status, duration at work, and clock-in time if available.
    c                 @    |dz  }|dz  dz  }|dz  }|dd|dd|dS )Ni  <   02:ro   )clssecondshoursminutess       r;   _format_secondszCheckingStatus._format_seconds  s?    4T>b(B,1WRL'"66r<   c                    t         j                  j                  |j                  j                        j                  d      j                         }d }|j                  j                  j                         d   }t        j                  t        |            }d}d }t        j                         }t         j                  j                  |j                  j                  |      j                  d      j                         }|r=|j                  j                  d      }|j                  rd}nd}t!        |||d	d
      S t!        |||dd
      S )N)r   z-idforecasted_at_work_secondsF)r   r   rM   z%I:%M %pT)rQ   durationr   rO   rP   )rQ   rc  clock_in_time)r   rZ   r   rs   r   order_byr   get_forecasted_at_workrW  r`  intr   rI   r   rX   clock_out_dater   )	r^   r_   attendance_activityrc  work_secondsrQ   rd  rW   attendance_activity_firsts	            r;   rU   zCheckingStatus.get  s/   &&--',,:S:S-TXe_UW 	
 ||00GGI(
 "11#l2CD&&--#LL55U .  Xm$UW 	" 5>>GG
SM"11%8W  8mT
 	
r<   N)	rj   rk   rl   rm   r   rn   classmethodr`  rU   ro   r<   r;   rW  rW    s)     **7 7#
r<   rW  c                       e Zd ZdZegZd Zy)MailTemplateViewz
    Retrieves a list of recruitment mail templates.

    Method:
        get(request): Returns all recruitment mail templates.
    c                     t         j                  j                         }t        |d      }t	        |j
                  d      S r  )r"   rZ   r   r-   r   r6   )r^   r_   	instancesr   s       r;   rU   zMailTemplateView.get=  s3    +33779	+IDA

44r<   N)rj   rk   rl   rm   r   rn   rU   ro   r<   r;   rn  rn  3  s     **5r<   rn  c                       e Zd ZdZegZd Zy)ConvertedMailTemplateConvertz
    Renders a recruitment mail template with data from a specified employee.

    Method:
        put(request): Renders the mail template body with employee and user data and returns the result.
    c                    |j                   j                  dd       }|j                   j                  dd       }t        j                  j	                  |      j                         }t        j                  j	                  |      j                         }t        j                  |j                        }t        j                  ||j                  j                  d      }|j                  |      }t        |      S )Ntemplate_idr   r   r   r^   )r6   rU   EmployeerZ   r   r   r"   r   TemplatebodyContextrs   r   renderr   )	r^   r_   rt  r   rF   bdytemplate_bdycontext
render_bdys	            r;   r   z ConvertedMailTemplateConvert.putM  s    ll&&}d;ll&&}d;##**k*:@@B%--444DJJL((2""!7<<+D+DE
 "((1

##r<   N)rj   rk   rl   rm   r   rn   r   ro   r<   r;   rr  rr  C  s     **
$r<   rr  c                       e Zd ZdZegZd Zy)OfflineEmployeeMailsendz
    Sends an email with attachments and rendered templates to a specified employee.

    Method:
        post(request): Renders email templates with employee and user data, attaches files, and sends the email.
    c           
      t   |j                   j                  d      }|j                   j                  dd      }|j                   j                  dd      }|j                  j                  d      }|D cg c])  }|j                  |j                         |j                  f+ }}t               }|j                  }	t        j                  j                  |      }
|j                   j                  d      }t        t        j                  j                  |      j                  dd	
            }|D ]  }t        j                   |      }t        j"                  |
|j$                  j&                  d      }|j)                  |      }|j+                  dt-        |i dd      j.                  df        t        j                   |      }t        j"                  |
|j$                  j&                  d      }|j)                  |      }t1        |||	|
j2                  j4                  g      }d|_        ||_        	 |j;                          |
j2                  j4                  rt=        d|
j?                                S t=        d|
j?                                S c c}w # t@        $ r}t=        d      cY d }~S d }~ww xY w)Nr   subjectr/   rx  other_attachmentsr   template_attachments)id__inT)flatru  DocumentF)pathtitlezapplication/pdfhtmlzMail sent to zEmail not set for zSomething went wrong)!POSTrU   FILESgetlistnamereadcontent_typer   dynamic_usernamerv  rZ   r3   r"   r   values_listr   rw  ry  rs   r   rz  appendr   contentr	   employee_work_infoemailcontent_subtypeattachmentsr   r   get_full_nameru   )r^   r_   r   r  r{  r  filer  email_backendhostrF   template_attachment_idsbodysr  r|  r}  r~  r  es                      r;   rh   zOfflineEmployeeMailsend.postd  s{   ll&&}5,,""9b1llvr*#MM112EFDU
<@TYY		T%6%67
 
 /0--##'';'7"),,"6"67M"N#++22. 3 k&tk,

  	D#,,T2L&&%w||/H/HIG &,,W5J Re:NVV%	  ((-""!7<<+D+DE
 "((1
((../	
 !''	4JJL**00-0F0F0H/I JKK"4X5K5K5M4N OPP_
`  	4233	4s+   3.J6AJ 8J 	J7"
J2,J72J7Nri   ro   r<   r;   r  r  Z  s     **64r<   r  N)Rr   r   r   r   djangor   django.confr   django.core.mailr	   django.db.modelsr
   r   r   r   r   django.httpr   django.shortcutsr   django.utils.decoratorsr   rest_framework.paginationr   rest_framework.permissionsr   rest_framework.responser   rest_framework.viewsr   attendance.modelsr   r   r   attendance.views.clock_in_outr   attendance.views.dashboardr   r   r   attendance.views.viewsbase.backendsr   base.methodsr   r    employee.filtersr!   recruitment.modelsr"   api_decorators.base.decoratorsr$   r%   api_methods.base.methodsr&   r'   &api_serializers.attendance.serializersr(   r)   r*   r+   r,   r-   r7   r>   rq   r{   r   r   r   r   r  r  r  r#  r'  r4  r>  rW  rn  rr  r  ro   r<   r;   <module>r     se   8 8    ) < < ! . 4 : 6 , ( N N + 3 
 % 0 : + 6 T A
W A
H@g @@LDW LD^$W $: $'  $FR7G R7j@<7 @<F;' ;<=RW =R@T7 T,5W 5
g 
>6 6$B+w B+J4
W 4
n5w 5 $7 $.@4g @4r<   