
    si]                     T   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 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l0m1Z1 d dl2m3Z3 ddl4m5Z5m6Z6 ddl7m8Z8m9Z9 ddl:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZB d 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 d) d*e      ZK G d+ d,e      ZL G d- d.e      ZM G d/ d0e      ZN G d1 d2e      ZO G d3 d4e      ZP G d5 d6e      ZQ G d7 d8e      ZR G d9 d:e      ZS G d; d<e      ZT G d= d>e      ZU G d? d@e      ZV G dA dBe      ZW G dC dDe      ZXyE)F    )datedatetime	timedeltatimezone)template)settings)EmailMessage)Case	CharFieldFValueWhen)	QueryDict)get_object_or_404)method_decoratorstatus)PageNumberPagination)IsAuthenticated)Response)APIView)
AttendanceAttendanceActivityEmployeeShiftDay)*)	clock_out)find_expected_attendancesfind_late_comefind_on_time)ConfiguredEmailBackend)generate_pdfis_reportingmanager)HorillaMailTemplate)EmployeeFilter   )manager_permission_requiredpermission_required)groupby_querysetpermission_based_queryset)AttendanceActivitySerializer$AttendanceLateComeEarlyOutSerializerAttendanceOverTimeSerializerAttendanceRequestSerializerAttendanceSerializerMailTemplateSerializer UserAttendanceDetailedSerializerUserAttendanceListSerializerc                     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        J/var/www/python-projects/worksol/horilla_api/api_views/attendance/views.pyr;   r;   1   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                 4   |j                   j                  j                         s]	 |j                   j                  j                         j                  j
                  r/ddlm}  |       }|j                  |      }|j                  dk7  r|S 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
      }t1        ||      \  }}}||kD  rh||kD  rc|	t3        d      z
  }|j%                  d      j'                         }t(        j*                  j                  |      }t1        ||      \  }}}|}
|}t5        ||	|
|||||||
       t7        ddid      S t7        ddi      S t7        ddid      S #  Y 	xY w)Nr   &GeoFencingEmployeeLocationCheckAPIView   r   r   %A)dayz%H:%Mtimez12:00)rH   shift   )days)
employee
date_todayattendance_daterH   nowrJ   minimum_hour
start_timeend_timein_datetimemessagez
Clocked-Inr   errorzOYou Don't have work information filled or your employee detail neither entered zAlready clocked-in  )useremployee_getcheck_onlineget_companygeo_fencingstartgeofencing.viewsrE   poststatus_codeemployee_existsr   rP   __dict__getshift_idr   todaystrftimelowerr   objectsrI   strtime_secondsshift_schedule_todayr    clock_in_attendance_and_activityr   )selfrequestrE   location_api_viewresponserM   	work_infodatetime_nowrJ   rN   rO   rH   rP   now_secmid_day_secrQ   start_time_secend_time_secdate_yesterdayday_yesterdays                       r?   r_   zClockInAPIView.postF   sn   ||((557	<<,,88:FFLLW(N(P%055g>H++s2' #2'":Hi#<<>L##J/&//I1!**!ZZ\
##''/!(J", ))$/557&..22s2;lln--g6##''/!,,//8C)#.-g6=Q5>:nl "L0 #W, *4iQ6G)G(6(?(?(E(K(K(M(8(@(@(D(D(D(W0]%P Cnl +9+0%)$3!--) ,  L 9#FFn 
 $89#FFss   A&J JN__name__
__module____qualname____doc__r   permission_classesr_    r@   r?   rB   rB   <   s     **CGr@   rB   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                    	 |j                   j                  j                         j                  j                  r/ddlm}  |       }|j                  |      }|j                  dk7  r|S |j                   j                  j                         r|t        j                         }t        j                         j                         }t        j                         }	 t        t!        |j                   |||             t#        ddid      S t#        dd	id
      S #  Y xY w# t$        $ r }t&        j)                  d|       Y d }~:d }~ww xY w)Nr   rD   rF   )rX   r   rI   r   rU   zClocked-Outr   zGot an error in clock_outzAlready clocked-outrW   )rX   rY   r[   r\   r]   r^   rE   r_   r`   rZ   r   re   r   rP   rI   r   Requestr   	ExceptionloggerrV   )	rl   rm   rE   rn   ro   current_datecurrent_timecurrent_datetimerV   s	            r?   r_   zClockOutAPIView.post   s   		||((446BBHHS$J$L!,11':''3.#O <<$$113::<L#<<>..0L'||~A$\\))!1	  M :3GG
 $9:3GG+	"  A8%@@As$   A&D 0D D	E(EENrx   r~   r@   r?   r   r      s     **Hr@   r   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)
AttendanceValidationConditionrh   firstri   minimum_overtime_to_approver   filterallrX   r)   )rl   rm   type	conditionminotquerysetrX   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instancerF   r   r   groupby_fieldTmany)r   r   r.   r   r:   r   filterset_classGETqsrc   build_absolute_urir(   r   paginate_querysetget_paginated_response)rl   rm   r   r   
attendance
serializerattendancesattendances_filter_queryset
field_nameurl	paginaterpages               r?   rc   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r:   rF   r   employee_idrO   r   rO   rV   @Attendance for this employee on the current date already exists.rW   )r.   r:   is_validsaver   rc   r   re   r   rh   r   existserrorsrl   rm   r   r   rO   s        r?   r_   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.  r   r   r:   rF   non_field_errorsz?The fields employee_id, attendance_date must make a unique set.z1The employee already has attendance on this date.rW   )
r   rh   rc   DoesNotExistr   r.   r:   r   r   r   )rl   rm   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)monthr   deletedrF   r   zerror:rW   )r   rh   rc   rO   rf   rg   r   employee_overtimer   lastattendance_overtime_approveri   overtimeattendance_overtimeformat_timer   deleter   r   )	rl   rm   r   r   r   r   total_overtimeattendance_overtime_secondsrV   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)ry   rz   r{   r|   r   r}   AttendanceFiltersr   r   rc   r&   r_   r   r'   r   r   r~   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eg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_redirectrF   r   )r   rh   r   r9   r   notifysendrX   rY   r   employee_user_idrO   r   rl   rm   r   r   s       r?   r   zValidateAttendanceView.putQ  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ry   rz   r{   r|   r   r}   r   r~   r@   r?   r   r   G  s     **$r@   r   c                       e Zd ZdZeg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   rV   rW   r   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   rF   )r   rh   r   r9   r   r   strr   r   r   rX   rY   r   r   rO   rl   rm   r   r   Es        r?   r   zOvertimeApproveView.putp  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   r~   r@   r?   r   r   f  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   rF   r   T)is_validate_requestr   )rm   r   r   )employee_id__employee_user_idr   r   r   )r   rh   rc   r-   r   r:   r   filtersubordinatesrX   r   r   r   r   r(   r   r   serializer_classr   )rl   rm   r   r   r   requestsrequest_filtered_querysetr   r   
pagenationr   s              r?   rc   zAttendanceRequestView.get  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   rF   r   r   rO   r   rV   r   rW   r   )r-   r:   r   r   r   rc   r   re   r   rh   r   r   r   r   s        r?   r_   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_requestTFrF   r   r   )r   rh   rc   r-   r:   r   r   r   r   request_typejsondumps	serializerequested_datarequest_descriptionr   is_validate_request_approvedr   r   )rl   rm   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)ry   rz   r{   r|   r-   r   r   r}   rc   r_   r&   r   r~   r@   r?   r   r     s>     3)*B<7( !!?@7 A7r@   r   c                   2    e Zd ZdZeg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   rO   clock_in_dateclock_inrV   rW   r   r   approvedrF   r~   )r   rh   rc   rO   attendance_clock_in_dateattendance_clock_inr   r  r   r  r   r  r   loadsr   r9   r	  r  r   r   creater   r   r   )
rl   rm   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)ry   rz   r{   r|   r   r}   r&   r   r~   r@   r?   r  r    s+     ** !?@7< A7<r@   r  c                       e Zd ZdZeg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   rV   rW   r   r   successrF   )r   rh   rc   r   r   rX   r"   has_permr  r   r  r  r   r   r   r   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   r~   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   rF   r   )r   z"attendance.view_attendanceovertimer   Tr   )r   AttendanceOverTimer,   r   r:   AttendanceOverTimeFilterr   r   r   rX   r   rc   r   r(   r   r   r   )rl   rm   r   attendance_otr   r   r   self_accountr)   r   r   r   r   s                r?   rc   zAttendanceOverTimeView.getR  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   rF   r   rW   )r,   r:   r   r   r   r   )rl   rm   r   s      r?   r_   zAttendanceOverTimeView.postj  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   rF   r   rW   )r   r  r,   r:   r   r   r   r   )rl   rm   r   r!  r   s        r?   r   zAttendanceOverTimeView.putr  s^    )*<D1"

  OOJOOC88
))#66r@   z$attendance.delete_attendanceovertimec                 b    t        t        |      }|j                          t        ddid      S )Nr   rU   zOvertime deleted successfully   r   )r   r  r   r   r   s       r?   r   zAttendanceOverTimeView.delete}  s.    &'9bA
$CDSQQr@   r  )ry   rz   r{   r|   r   r}   rc   r&   r_   r   r   r'   r   r~   r@   r?   r  r  E  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   rF   r   )LateComeEarlyOutFilterr   r+   r   r   r:   rl   rm   r   r:   r   s        r?   rc   zLateComeEarlyOutView.get  s1    %gkk29$''M

44r@   c                 b    t        t        |      }|j                          t        ddid      S )Nr   rU   zAttendance deleted successfullyr&  r   )r   AttendanceLateComeEarlyOutr   r   r   s       r?   r   zLateComeEarlyOutView.delete  s.    &'AbI
$EFsSSr@   r  )ry   rz   r{   r|   r   r}   rc   r   r~   r@   r?   r(  r(    s     **5
Tr@   r(  c                       e Zd ZdZeg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   rh   r   r*   r   r:   r,  s        r?   rc   zAttendanceActivityView.get  s3    !))--/1$TB

44r@   r  ry   rz   r{   r|   r   r}   rc   r~   r@   r?   r0  r0    s     **5r@   r0  c                       e Zd ZdZeg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 )NrG   )re   week_day)
start_date)r6  r   d   z.2fmarked_attendances_ratiorF   r   )	r   re   rf   rg   r   r   lenr   r   )
rl   rm   re   r6  on_time	late_comelate_come_objmarked_attendancesexpected_attendancesr9  s
             r?   rc   zTodayAttendance.get  s     >>$'--/wehG"e4	I*W48(K#$ 1$&)==DSI % ')AB3
 	
r@   Nr2  r~   r@   r?   r4  r4    s     **
r@   r4  c                       e Zd ZdZeg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         j                  j                  |j                  j                        j                  d      j                         }|j                  j                  d      s|rft        dt        j                         i      j                  j                  d      j                  d      j                         }t        d|id	
      S t        ddit        j                   
      S )Nreporting_manager_idr   zemployee.view_enployee
not_in_yetTemployee_work_info__isnull	is_activecountrF   r   rV   Permission denied)EmployeeWorkInformationrh   r   rX   rY   onlyr   r  r$   r   re   r   excluderJ  r   r   HTTP_403_FORBIDDEN)rl   rm   
is_managerrJ  s       r?   rc   zOfflineEmployeesCountView.get  s    #++22%,\\%>%> 3  T$ZVX 	 <<  !9:jdjjl;<GGtG<$'	  We,S99)*63L3L
 	
r@   Nr2  r~   r@   r?   rA  rA    s     **
r@   rA  c                   "    e Zd ZdZegZd Zd Zy)OfflineEmployeesListViewz^
    Li sts active employees who have not clocked in today, including their leave status.
    c                    |j                   }t        |dd       }t        j                         }t        j
                  j                  |      j                  dd      }|j                  d      rt        j
                  j                         }nN|j                         r!t        j
                  j                  |      }nt        dd	it        j                  
      S t        d|i|      j                   j#                  d      j                  d      j%                  d      }| j'                  |      }t)               }	|	j+                  ||      }
|	j-                  |
      S )NrY   rC  r   Tflatzemployee.view_employeeid__inrV   rK  r   rE  r   rF  rH  employee_work_info)rX   getattrr   re   rL  rh   r   values_listr  Employeer   r   r   r   rO  r$   r   rN  select_relatedget_leave_statusr   r   r   )rl   rm   rX   rM   re   managed_employee_idsbase_querysetfiltered_qsleave_statusr   r   s              r?   rc   zOfflineEmployeesListView.get  s7   ||46

  7>>EE!)  F  

+m$+
/ 	
 ==12$,,002M!((*$,,33;O3PM-.v7P7P  L%0=IR48VdV#^01	 	 ,,[9)+
++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   re   distinctannotater
   r   r   r   r   valuesr   	MEDIA_URL)rl   r   re   employees_with_leave_statusrM   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)ry   rz   r{   r|   r   r}   rc   r]  r~   r@   r?   rR  rR    s     **!7F/+r@   rR  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:r~   )clssecondshoursminutess       r?   _format_secondszCheckingStatus._format_secondsR  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 #  t!        |||d	d
      cY S xY w)Nr   -idforecasted_at_work_secondsF)r   r  rT   z%I:%M %pT)r   durationr  rF   r   )r   r  clock_in_time)r   rh   r   rX   rY   order_byr   get_forecasted_at_workrw  r  intr   rP   r  rf   clock_out_dater   )	rl   rm   attendance_activityr  work_secondsr   r  re   attendance_activity_firsts	            r?   rc   zCheckingStatus.getY  s`   &&--',,:S:S-TXe_UW 	
 ||00GGI(
 "11#l2CD&&--#LL55U .  Xm$UW 	"  9 B B K KJ W&55"F!F#&,(0(5
  #    8mT
 	
%8W s   <E E*N)	ry   rz   r{   r|   r   r}   classmethodr  rc   r~   r@   r?   rw  rw  H  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#   rh   r   r/   r   r:   )rl   rm   	instancesr   s       r?   rc   zMailTemplateView.get  s3    '//335	+IDA

44r@   Nr2  r~   r@   r?   r  r    s     **5r@   r  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   rl   )r:   rc   r[  rh   r   r   r#   r   TemplatebodyContextrX   rY   renderr   )	rl   rm   r  r   rM   bdytemplate_bdycontext
render_bdys	            r?   r   z ConvertedMailTemplateConvert.put  s    ll&&}d;ll&&}d;##**k*:@@B!))00K0@FFH((2""!7<<+D+DE
 "((1

##r@   Nr   r~   r@   r?   r  r    s     **
$r@   r  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   subjectr3   r  other_attachmentsr   template_attachmentsrV  TrT  r  DocumentF)pathtitlezapplication/pdfhtmlzMail sent to zEmail not set for zSomething went wrong)!POSTrc   FILESgetlistnamereadcontent_typer    dynamic_usernamer[  rh   r7   r#   r   rZ  r   r  r  rX   rY   r  appendr!   contentr	   rX  emailcontent_subtypeattachmentsr   r   get_full_namer   )rl   rm   r   r  r  r  filer  email_backendhostrM   template_attachment_idsbodysr  r  r  r  r  es                      r?   r_   zOfflineEmployeeMailsend.post  s{   ll&&}5,,""9b1llvr*#MM112EFDU
<@TYY		T%6%67
 
 /0--##'';'7"),,"6"67M"N''... / 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Nrx   r~   r@   r?   r  r    s     **64r@   r  c                       e Zd ZegZeZd Zy)UserAttendanceViewc                 B   |j                   j                  j                  }t        j                  j                  |      j                  d      }t               }d|_        |j                  ||      }| j                  |d      }|j                  |j                        S )Nr  r     Tr   )rX   rY   r   r   rh   r   r  r   	page_sizer   r   r   r:   )rl   rm   r   attendance_queryset	paginatorr   r   s          r?   rc   zUserAttendanceView.get  s    ll//22(0077# 8 

(5/ 	 )*	 	**+>H**4d*;
//
@@r@   N)ry   rz   r{   r   r}   r0   r   rc   r~   r@   r?   r  r    s    )*7Ar@   r  c                       e Zd ZegZd Zy)AttendanceTypeAccessCheckc                 P   |j                   }|j                  j                  }|j                  d      rt	        d      S t
        j                  j                  |      j                  d      j                         }|rt	        d      S t	        ddit        j                        S )Nr   rF   r   rC  r   rV   rK  )rX   rY   r   r  r   rL  rh   r   rM  r   r   rO  )rl   rm   rX   r   rP  s        r?   rc   zAttendanceTypeAccessCheck.get	  s    ||''**==563'' $++222TT$ZVX 	 3'')*63L3L
 	
r@   Nry   rz   r{   r   r}   rc   r~   r@   r?   r  r    s    )*
r@   r  c                       e Zd ZegZd Zy)UserAttendanceDetailedViewc                     t        t        |      }|j                  |j                  j                  k(  r"t        |      }t        |j                  d      S t        ddit        j                        S )Nr   rF   r   rV   rK  )
r   r   r   rX   rY   r0   r   r:   r   rO  )rl   rm   r   r   r   s        r?   rc   zUserAttendanceDetailedView.get!  s_    &zb9
!!W\\%>%>>9*EJJOOC88)*63L3L
 	
r@   Nr  r~   r@   r?   r  r    s    )*
r@   r  N)Yr   r   r   r   djangor   django.confr   django.core.mailr	   django.db.modelsr
   r   r   r   r   django.httpr   django.shortcutsr   django.utils.decoratorsr   rest_frameworkr   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"   base.modelsr#   employee.filtersr$   api_decorators.base.decoratorsr&   r'   api_methods.base.methodsr(   r)   &api_serializers.attendance.serializersr*   r+   r,   r-   r.   r/   r0   r1   r;   rB   r   r   r   r   r   r  r  r  r(  r0  r4  rA  rR  rw  r  r  r  r  r  r  r~   r@   r?   <module>r     s   8 8    ) < < ! . 4 ! : 6 , ( N N + 3 
 % 0 : + + T	 	 	MGW MG`)Hg )HXLDW LD^$W $>"$' "$JR7G R7jB<7 B<J;' ;@=RW =R@T7 T,5W 5 
g 
B
 
@Y+w Y+x>
W >
B5w 5 $7 $.@4g @4FA A&
 
0

 

r@   