
    vg                     x   d dl Z d dlZd dlZd dlZd dlZd dl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 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)m*Z*m+Z+m,Z,m-Z- d dl.m/Z/m0Z0 d dl1m2Z2 d dl3m4Z4 d dl5m6Z6 d dl7m8Z8 d dl9m:Z:m;Z; d dl<m=Z= d dl>m?Z?  ej                  eA      ZBej                  ej                  ej                  ej                  ej                  ej                  ej                  dZJd e!d      fd e!d      fd e!d       fgZKd!d"gZLd# e!d$      fd% e!d&      fd' e!d(      fgZMd) e!d*      fd+ e!d,      fd- e!d.      fd/ e!d0      fd1 e!d2      fd3 e!d4      fd5 e!d6      fd7 e!d8      fd9 e!d:      fd; e!d<      fd= e!d>      fd? e!d@      fgZNg dA e!dB      fdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`daZOdb e!dc      fdd e!de      fdf e!dg      fgZPdh e!di      fdj e!dk      fgZQdl e!dm      fdn e!do      fdp e!dq      fgZRdr e!ds      fdt e!du      fgZSdv e!dw      fdx e!dy      fdz e!d{      fd| e!d}      ffZTdv e!dw      fdx e!dy      fd| e!d}      ffZUd~ e!d      fd) e!d      fd+ e!d      fd- e!d      fd/ e!d      fgZVd~ e!d      fd) e!d      fd+ e!d      fd- e!d      fd/ e!d      fd1 e!d      fd3 e!d      fgZW G d de6      ZX G d de6      ZY G d de6      ZZd dlm[Z[  G d de6      Z\d Z] G d de6      Z^ G d dej                        Z` G d de6      Za G d de6      Zb G d de6      Zc G d dej                        Zd G d de6      Ze ej                  d      r G d de6      Zg G d de6      Zh ej                  d      r G d de6      Zi G d de6      Zj ej                  d      r G d de^      Zk eee^      d        Zly)    N)datedatetime	timedelta)relativedelta)apps)settings)messages)ValidationError)default_storage)models)Q)	post_savepre_save)receiver)timezone)gettext_lazy)HorillaCompanyManager)get_date_range)CompanyCompanyLeaves
DepartmentHolidaysJobPositionMultipleApprovalConditionclear_messages)EmployeeEmployeeWorkInformation)horilla_middlewares)get_horilla_model_class)HorillaModelget_diff)HorillaAuditInfoHorillaAuditLog)calculate_requested_days)LeaveClashThread)equalnotequalltgtlege	icontainsfull_dayzFull Day
first_halfz
First Halfsecond_halfzSecond Half)yesYes)noNoyearlyYearlymonthlyMonthlyweeklyWeekly1Jan2Feb3Mar4Apr5May6Jun7Jul8Aug9Sep10Oct11Nov12Declast dayzLast Day)r;   1st)r=   2nd)r?   3rd)rA   4th)rC   5th)rE   6th)rG   7th)rI   8th)rK   9th)rM   10th)rO   11th)rQ   12th)1313th)1414th)1515th)1616th)1717th)1818th)1919th)2020th)2121th)2222th)2323th)2424th)2525th)2626th)2727th)2828th)2929th)3030th)3131thdayDaymonthMonthyearYearpaidPaidunpaidUnpaidno carryforwardzNo Carry ForwardcarryforwardzCarry Forwardcarryforward expirezCarry Forward with Expirejob_positionJob Positionjob_rolezJob Role	requested	RequestedapprovedApproved	cancelled	CancelledrejectedRejected0z
First WeekzSecond Weekz
Third WeekzFourth Weekz
Fifth WeekMondayTuesday	WednesdayThursdayFridaySaturdaySundayc            
           e Zd Z ej                  ddd      Z ej                  dd      Z ej                  dd      Z ej                  de	d	      Z
 ej                  dd
      Z ej                  ded	      Z ej                  d      Z ej                  dd
      Z ej                  d      Z ej                  d ed            Z ej                  dedd      Z ej                  ded      Z ej                  dedd      Z ej                  ddde      Z ej                  ded	      Z ej                  dd      Z ej@                  dd      Z! ej                  dedd      Z" ejF                  dd      Z$ ej                  de%ddd      Z& ej                  de%ddd ed            Z' ej                  de%d	      Z( ej                  de%d	      Z) ej                  d      Z* ejV                  e,ddejZ                        Z. e/d      Z0 G d d       Z1d! Z2d" Z3d# Z4d$ Z5 fd%Z6d& Z7 xZ8S )'	LeaveTypeTzleave/leave_iconnullblank	upload_to   F)
max_lengthr   )r   r   r   r   choicesdefault   )r   r   r   r   zIs encashabler   verbose_namer   r   r   r   )r   r   r   )r   r   r   r   
   )r   r   r   r   r   )r   r   r1   )r   r   r   r   r   r3   zRequire Attachment)r   r   r   r   r   r   r   editable	on_delete
company_idrelated_company_fieldc                       e Zd ZdgZy)LeaveType.Meta-idN__name__
__module____qualname__ordering      /var/www/horilla/leave/models.pyMetar      	    7r   r   c                     d| j                    d}| j                  rA| j                  j                   }t        j                  |      r| j                  j                  }|S )zV
        Method will retun the api to the avatar or path to the profile image
        z!https://ui-avatars.com/api/?name=z&background=random)nameiconr   existsurl)selfr   full_filenames      r   
get_avatarzLeaveType.get_avatar   sK     2$))<NO99 IINNM%%m4iimm
r   c                 ~   t        j                         j                         | j                  sy fd}| j                  dk(  rt        | j                         |t        | j                        | j                        }}t        j                  t        j                  ||      j                         k  z   ||      j                         }|S | j                  dk(  rj                  }t        j                  | ||| j                              j                         }|k  rF|dz  dz   }j                  |dk(  z   }t        || ||| j                              j                         }|S | j                  dk(  r>t        | j                     }|j                         z
  dz  xs d}t        |      z   }|S d }|S )	Nc                 j    |dk(  r#t        j                  j                  |       d   S t        |      S )NrS   r   )calendar
monthranger   int)r   r   todays     r   get_reset_dayz;LeaveType.leave_type_next_reset_date.<locals>.get_reset_day   s;     *$ ##EJJ6q9 Xr   r5   r7      r   r9      days)r   nowr   resetreset_basedr   reset_month	reset_dayr   r   	WEEK_DAYSweekdayr   )	r   r   r   r   
reset_dater   target_weekdaydays_until_resetr   s	           @r   leave_type_next_reset_datez$LeaveType.leave_type_next_reset_date   s   ##%zz	 x'T--.D$$%t~~13E "

huzz5#>CCEMN df	 4 ) *KKE!

E=#Gdf  E!q(zzUaZ0%%udnn!E$&   )&t~~6N . @AEJ0@!AAJ
  Jr   c                     | j                   }| j                  dk(  r|t        |      z   }|S | j                  dk(  r|t        |      z   }|S |t        |      z   }|S )Nr   r   r   monthsyears)carryforward_expire_incarryforward_expire_periodr   )r   assigned_dateperiodexpired_dates       r   set_expired_datezLeaveType.set_expired_date  sp    ,,**e3(=f+EEL  ,,7(=+GGL  )=v+FFLr   c                     | j                   rFt        j                  j                  d      j	                         dk\  rt        t        d            y y )NTis_compensatory_leaver   z*Compensatory Leave Request already exists.)r   r   objectsfiltercountr
   _)r   argskwargss      r   cleanzLeaveType.clean  sL    %%  ''d'CIIKqP%a(T&UVV Q &r   c                    | j                   dk7  r!| j                  t        j                  | _        | j                  r;t
        j                  j                  | j                        j                  rd| _        | j                   dk(  r-| j                  s!| j                  | j                        | _	        t        | 5          y )Nr   idTr   )r   )carryforward_typecarryforward_maxmathinfpkr   r   getr   carryforward_expire_dater   
created_atsupersaver   r   r   	__class__s      r   r	  zLeaveType.save"  s    ""&77%%-$(HHD!77y((,,,8NN)-D& ""&;;11,0,A,A"oo -B -D) 	r   c                     | j                   S Nr   r   s    r   __str__zLeaveType.__str__5      yyr   )9r   r   r   r   
ImageFieldr   	CharFieldr   colorPAYMENTpayment
FloatFieldr   TIME_PERIOD	period_inBooleanFieldlimit_leave
total_daysr   r   is_encashableRESET_BASEDr   MONTHSr   DAYSr   r   reset_weekendCARRYFORWARD_TYPEr   r  IntegerFieldr   r   	DateFieldr  CHOICESrequire_approvalrequire_attachmentexclude_company_leaveexclude_holidayr   
ForeignKeyr   PROTECTr   r   r   r   r   r   r   r   r	  r  __classcell__r  s   @r   r   r      s   6$d>PQD6r6DF$26Ef"gxPGF43E   BUSI%&%%d3K"""a8JF.E'F''AoDVWM"&""	K #&""b&MK   B4tTI$F$$DiM )((0:K )v((d$?0V00d$G!1!1!1{T"  0v//TF'v''wTu *))+, -F,,w 'f&&"gtTO/F//>"""dUfnnJ $,GG 
+Z	W
&r   r   c                   6   e Zd Z ej                  dd ed            Z ej                   ed            Z ej                  dd ed      	      Z	 ej                  d ed
            Z ej                  eddej                        Z ed      Zd Zy)Holidayr   FName)r   r   r   
Start Dater   TEnd Dater   r   r   	Recurringr   r   r   r   c                     | j                   S r  r  r  s    r   r  zHoliday.__str__C  r  r   N)r   r   r   r   r  r   r   r$  
start_dateend_dater  	recurringr*  r   r+  r   r   r   r  r   r   r   r/  r/  9  s    6rAfIND!!!q?JvTAjMRH###E+OI"""dUfnnJ $,GGr   r/  c                       e Zd Z ej                  dedd      Z ej                  de      Z ej                  e
ddej                        Z ed      Z G d	 d
      Zd Zy)CompanyLeaved   Tr   )r   r   Fr   r   r   c                       e Zd ZdZy)CompanyLeave.Meta)based_on_weekbased_on_week_dayNr   r   r   unique_togetherr   r   r   r   r>  Q  s    @r   r   c                     t        t              j                  | j                         dt        t              j                  | j
                         S Nz | )dictr   r  r@  WEEKSr?  r  s    r   r  zCompanyLeave.__str__T  s>    y/%%d&<&<=>c$u+//RVRdRdBeAfggr   N)r   r   r   r   r  rF  r?  r   r@  r*  r   r+  r   r   r   r   r  r   r   r   r;  r;  G  sq    $F$$TM )((CK"""dUfnnJ $,GGA Ahr   r;  )Sumc            
       j    e Zd Z ej                  eej                  d ed            Z ej                  e	ej                  ddd ed            Z ej                  d ed	      
      Z ej                  d ed      
      Z ej                  d ed      
      Z ej                   ej$                   ed      
      Z ej                   dd ed            Z ej                   dd ed            Z ed      Z edeg      Z G d d      Zd Zd Zd Zd Zd Z d Z! fdZ" xZ#S )AvailableLeaveavailable_leaver   )r   related_namer   employee_available_leaveT
Leave type)r   rK  r   r   r   r   zAvailable Daysr   zCarryforward DayszTotal Leave DayszAssigned DatezLeave Reset Dater   r   r   zCarryForward Expired Date+employee_id__employee_work_info__company_idr   history_setrK  basesc                       e Zd ZdZy)AvailableLeave.Metaleave_type_idemployee_idNrA  r   r   r   r   rT    s    :r   r   c                 8    | j                    d| j                   S rD  rW  rV  r  s    r   r  zAvailableLeave.__str__  s!    ""#3t'9'9&:;;r   c                     t        |t              r$t        j                  |d      j	                         }| j
                  j                         }|r||k  r| j
                  j                  S y)N%Y-%m-%dr   )
isinstancestrr   strptimer   rV  r   r  )r   r   next_reset_dates      r   forcasted_leaveszAvailableLeave.forcasted_leaves  sZ    dC $$T:6;;=D,,GGI$6%%000r   c                    | j                   j                  dk7  rP| j                   j                  | j                  k\  r| j                  | _        n| j                   j                  | _        | j                   j
                  | _        y )Nr   )rV  r   r  total_leave_dayscarryforward_daysr  available_daysr  s    r   update_carryforwardz"AvailableLeave.update_carryforward  sg    //3DD!!22d6K6KK)-)>)>&)-););)L)L&"00;;r   c                 x   |j                   j                  dk(  r|j                   j                  }|dk(  r+|t        dd      z   }||k  r|}|S |t        dd      z   }|S |t        dt	        |            z   }||k  r|}|S |t        dt	        |            z   }|S |j                   j                  dk(  r`d|j                         t	        |j                   j                        z
  dz
  z
  }|dk7  r|t        |dz  	      z   }|S |t        d	      z   }|S t	        |j                   j                        }|j                   j                  }|dk(  r-|t        d|d
      z   }||k  r|}|S |t        d|d
      z   }|S |t        d|t	        |      
      z   }||k  r|}|S |t        d|t	        |      
      z   }|S )Nr7   rS   r      )r   r   r   r9   r   r   )r   r   r   )rV  r   r   r   r   
isoweekdayr!  r   )r   r   rJ  r   	temp_dater   tempr   s           r   set_reset_datezAvailableLeave.set_reset_date  s0   ((44	A'55??IJ&)M,KK	 9,!*Jb _ "/aR1P!PJ^ Y *MI,WW	 9,!*JT Q "/ c)n2 "JP I **66(B((*o33AABCD
 qy*]-KK
: 7 +]-BB
6 3 o;;GGHK'55??IJ&)M;B- 	 !9,!*J"  "/{2 "J  *M;C	N- 	 !9,!*J 	 "/{I2 "J r   c                     t         j                  j                  | j                  | j                  d      j                  t        d            }|d   r|d   S dS )Nr   )rV  rW  statusrequested_days)	total_sumro  r   )LeaveRequestr   r   rV  rW  	aggregaterG  )r   leave_takens     r   rr  zAvailableLeave.leave_taken  sb    "**11,,(( 2 
 )c"23)
4	 	 ,7{+C{;'JJr   c                 8   |j                   j                  }|j                   j                  dk(  r|t        |      z   }n8|j                   j                  dk(  r|t        |      z   }n|t        |      z   }d|_        |j                   j
                  |_        |S )Nr   r   r   r   r   r   )rV  r   r   r   rc  r  rd  )r   rJ  r   r   r   s        r   r   zAvailableLeave.set_expired_date  s     ..EE((CCuL(=f+EEL**EEP(=+GGL(=v+FFL,-))8)F)F)Q)Q&r   c                    | j                   :| j                  j                  r$| j                  | j                  |       }|| _         | j                  j
                  dk(  r?| j                  }| j                  j                  r| j                  j                  }|| _        t        | j                  | j                  z   d      | _        t        | j                  d      | _
        t        | 4  |i | y )N)r   rJ  r   r   )r   rV  r   rk  r   r   r  r   maxrd  rc  rb  r  r	  )r   r   r   r   expiry_dater  s        r   r	  zAvailableLeave.save  s    ??"!!''!00"&"4"4d 1 
 #-//3HH,,K!!::"00II +D #D$7$7$:P:P$PRS T!$T%;%;Q!?d%f%r   )$r   r   r   r   r*  r   CASCADEr   rW  r   r+  rV  r  rd  rc  rb  r$  r   r   r   r   r   r   r   r$   r#   historyr   r  r`  re  rk  rr  r   r	  r,  r-  s   @r   rI  rI  [  sj   #&##..&z]	K &F%%../|_M 'V&&qqAQ?RSN)))"5 6 )v((CUAVW$F$$1_+=M "!!A.@,AJ $6##A.I,JL $KG "
G; ;<<7rK& &r   rI  c                 
   g }t         j                  j                  |       }|D ][  }|j                  }|j                  }||z
  }t        |j                  dz         D ]!  }|t        |      z   }|j                  |       # ] |S )Nr   r   )	RestrictLeaver   r   r7  r8  ranger   r   append)restrirestricted_datesrestricted_daysirestrict_start_daterestrict_end_dater  r   s           r   restrict_leavesr    s    #++22f2=O *llJJ&)<<
z*+ 	*A&15D##D)	*	* r   c            
       Z    e Zd Z ej                  eej                   ed            Z ej                  e	ej                   ed            Z ej                  d ed            Z ej                  ded ed	      
      Z ej                  dd ed            Z ej                  ded ed      
      Z ej&                  dd ed            Z ej*                  d ed            Z ej.                   ed      d      Z ej2                  ddd ed            Z ej                  ded ed      
      Z ej                  ej<                   ed            Z ej&                  d      Z  ej&                  d      Z! ej.                  d ed      d      Z" e#d e$g!      Z% ej                  eej                  ddd" ed#      $      Z& e'd%&      Z( G d' d(      Z)d) Z*d* Z+d:d+Z,d, Z-d- Z.d. Z/d/ Z0 fd0Z1 fd1Z2d2 Z3d3 Z4d4 Z5d5 Z6d6 Z7 fd7Z8d8 Z9d9 Z: xZ;S );rp  r   r   r   z
Leave TypeFr1  )r   r   r   r.   zStart Date Breakdown)r   r   r   r   Tr3  r4  zEnd Date BreakdownzRequested DaysrN  r   zLeave Clashes Countr   Description   )r   r   leave/leave_attachment
Attachment)r   r   r   r   r   StatuszCreated Dater   zReject Reason)r   r   r   rP  rQ  leave_request_createdz
Created By)r   r   r   rK  r   rO  r   c                       e Zd ZdgZy)LeaveRequest.Metar   Nr   r   r   r   r   r  R  r   r   r   c                     t        |       S r  r!   r  s    r   trackingzLeaveRequest.trackingU      ~r   c                 R    | j                    d| j                   d| j                   S rD  )rW  rV  rm  r  s    r   r  zLeaveRequest.__str__X  s+    ""#3t'9'9&:#dkk]KKr   c                     | t        j                         n| } t        j                  j	                  | |       }||j	                  |      }|S )a  
        Retrieve employees who are on leave on a given date (default is today).

        Args:
            today (date, optional): The date to check. Defaults to the current date
                                    in the server's local timezone.
            status (str, optional): The status to filter leave requests. If None, no filtering by status is applied.

        Returns:
            QuerySet: A queryset of LeaveRequest instances where employees are on leave on the specified date.
        start_date__lteend_date__gterm  )r   r   rp  r   r   )r   rm  querysets      r   employees_on_leave_todayz%LeaveRequest.employees_on_leave_today[  sR     !&

5''..! / 
 f5Hr   c                 6    | j                   j                         S )z^
        This method is used to return the total penalties in the late early instance
        )penaltyaccounts_setr   r  s    r   get_penalties_countz LeaveRequest.get_penalties_countq  s     ''--//r   c                     | j                   }| j                  }|| j                   }||z
  }g }t        |j                  dz         D ]!  }|t	        |      z   }|j                  |       # |S )z^
        :return: this functions returns a list of dates from start date to end date.
        r   )r7  r8  r{  r   r   r|  )r   request_start_daterequest_end_datern  requested_datesr  r   s          r   r  zLeaveRequest.requested_datesw  s{     "__==##),>>~**Q./ 	)A%	!4D""4(	) r   c                    g }t         j                  j                         }|D ]_  }|j                  }|j                  }||}||z
  }t        |j                  dz         D ]!  }|t        |      z   }|j                  |       # a |S )zN
        :return: this functions returns a list of all holiday dates.
        r   )	r   r   allr7  r8  r{  r   r   r|  )	r   holiday_datesholidaysholidayholiday_start_dateholiday_end_dateholiday_daysr  r   s	            r   r  zLeaveRequest.holiday_dates  s     ##'') 	+G!(!3!3&//'#5 +.@@L<,,q01 +)IaL8$$T*+	+ r   c                    ddl m} t        j                  j	                         }g }|D ]  }| r| j
                  j                  }n |j                         j                  }|j                  }|j                  }t        dd      D ]U  }|dk7  rt        j                  d       t        j                  ||      }		 |	t        |         }
|
D cg c]
  }|dk7  s	| }}|D ]d  }t        j                  | d|dd|dd	      j                         } |j                          t        |      k(  sO||vsT|j#                  |       f t        j                  d       t        j                  ||      }	|	D ]d  }|t        |         dk7  st        j                  | d|dd|t        |         dd	      j                         }||vsT|j#                  |       f X  |S c c}w # t$        $ r Y ow xY w)
zI
        :return: This function returns a list of all company leave datesr   )r   r      N   -02r[  )r   r   r   r   r  r7  r   r   r?  r@  r{  r   setfirstweekdaymonthcalendarr   r^  r   r|  
IndexError)r   r   company_leavescompany_leave_datescompany_leaver   r?  r@  r   month_calendarweeksr   weekdays_in_weeksweeks                 r   r  z LeaveRequest.company_leave_dates  s    	"&..224 + %	AM++!tzz|(()77M - ? ?q" A D(,,Q/%-%;%;D%%HN .s=/A B<A,NSSAXS,N),N#4 AC#+#4#4#'&%1SH =z$"df ! !-#6G2H H$(0C$C 3 : :4 @A ,,Q/%-%;%;D%%HN . A$5 671<#+#4#4#'&%1T#>O:P5QRT4U V *$ #df !  $+>> 3 : :4 @A/A%	AL #"1 -O & s7   :G(
G#G#AG(.G(3G(#G((	G54G5c                    t        | j                  | j                  | j                  | j                        | _        | j                  j                  dk(  r*| j                  j                  dk(  r| j                          n| j                          | j                  dv rd| _        n| j                         | _        t        | <  |i | | j!                          t"        j$                  j'                  | j(                        }d }d }|j+                         r@| j(                  j,                  j.                  }| j(                  j,                  j0                  }| j
                  }d}|d k7  r5d k7  r0t2        j$                  j'                  ||      j5                  d      }|d k7  r|D ]  }	|	j6                  }
|
dk(  r=t9        |	j:                        }t9        |	j<                        }||cxk  r|k  sJn M|	} nIt>        jA                  |	j6                        } tC        |      |	jD                        } |||      s|	} n |r| j                  d	k(  rtF        j$                  j'                  | 
      jI                          d}|jK                         }|D ]Y  }|dz  }tM        |tN              s tQ        | j(                  j,                  |      }tF        j$                  jS                  || |       [ y y y )Nr1   r   r   r   rW  F)
departmentr   condition_valuer{  r   leave_request_idr   )sequencer  
manager_id)*r%   r7  r8  start_date_breakdownend_date_breakdownrn  rV  r(  r)  exclude_all_leavesexclude_leavesrm  leave_clashes_countcount_leave_clashesr  r	  update_leave_clashes_countr   r   r   rW  r   employee_work_infodepartment_idr   r   order_bycondition_operatorfloatcondition_start_valuecondition_end_valueoperator_mappingr  typer  LeaveRequestConditionApprovaldeleteapproval_managersr\  r   getattrcreate)r   r   r   	work_infor  
conditionsemp_comp_idrn  applicable_condition	conditionoperatorstart_value	end_valueoperator_funcr  r  managersmanagerr  s                     r   r	  zLeaveRequest.save  s   6OOMM%%##	
 44=""22e;##%!;;33'(D$'+'?'?'AD$d%f%'')+33::tGWGW:X	
 ,,??MMM**==HHK,,$D [D%82::AA([ B h()  ' 	$77w&"'	(G(G"HK %i&C&C DI"nA	A/8,$4$8$89U9U$VM&:d>&:9;T;T&UO$^_E/8,  DKK;$>)1188$8OVVXH+==?H# A!'84%d&6&6&I&I7SG-55<<%%)& = 		 %?r   c                    t         |          }t        j                  j	                         }t
        j                  j                  | j                        }t        j                  j                  | j                        }|j                         r@| j                  j                  j                  }| j                  j                  j                  }t        t         j"                  dd       }|j$                  j&                  s]t(        j                  j+                         j,                  r5| j.                  t1        j2                         k  rt5        t7        d            |j$                  j&                  s|D ]  }|j8                  }	| j;                         }
g |j<                  r1t?        |j@                  j	                               dk(  rtC        |	      |j@                  j	                         rLg }|j@                  j	                         D ]  }|jE                  |        | j                  |v rntC        |	      |jF                  j	                         rL|jF                  j	                         D ]/  }tI        |jJ                        tI        |      k(  s%tC        |	      1 s/|jL                  k(  rGt?        |jN                  j	                               dk(  r!tQ        fd|
D              szt5        d      |jN                  j	                         s|jN                  j	                         v stQ        fd|
D              st5        d       |S )	Nr  r  requestz'Requests cannot be made for past dates.r   c              3   &   K   | ]  }|v  
 y wr  r   .0r   restri_dayss     r   	<genexpr>z%LeaveRequest.clean.<locals>.<genexpr>:  s     Itt{2I   zhYou cannot request leave for this date range. The requestesd dates are restricted, Please contact admin.c              3   &   K   | ]  }|v  
 y wr  r   r  s     r   r  z%LeaveRequest.clean.<locals>.<genexpr>@  s     "M44;#6"Mr  ))r  r   rz  r   r  r   r  rV  r   r   rW  r   r  r  job_position_idr  r   _thread_localsuseris_superuserEmployeePastLeaveRestrictfirstenabledr7  r   r   r
   r   r   r  include_alllenexclued_leave_typesr  r|  spesific_leave_typesr]  r   r  r   any)r   cleaned_datarestricted_leaveleave_type_instancer  emp_depemp_jobr  restrictr}  	requ_daysexcludedexcluedspesificr  r  s                 @r   r   zLeaveRequest.clean  s   w}(00446'//339K9K3L+33::tGWGW:X	&&99GGG&&99IIG-<<iN||(((00668@@??TZZ\1)!,U*VWW||((, *"! 002	  ((H88<<>?1D"1&"9K//335!H#+#?#?#C#C#E 1 01))X5&5f&=00446$,$A$A$E$E$G Bx}}-5H1II*9&*AKB  ++w6 5 5 9 9 ;<A IyII"1 !K#  "..224"h&;&;&?&?&AA""M9"MM&5 %O'" !"Q*"X r   c                    | j                         }| j                         }| j                         }t        t	        ||z               t        fd|D              }| j                  v s| j                  v r3| j                  dk(  s| j                  dk(  r| xj                  dz  c_
        | j                  |z
  | _
        y )Nc              3   &   K   | ]  }|v  
 y wr  r   )r  requested_datetotal_leavess     r   r  z2LeaveRequest.exclude_all_leaves.<locals>.<genexpr>L  s       
/=Nl* 
r  r0   r/         ?)r  r  r  listsetsumr7  r8  r  r  rn  )r   r  r  r  total_leave_countr  s        @r   r  zLeaveRequest.exclude_all_leavesG  s    ..0**,"668C0C CDE  
AP 
 
 OO|+t}}/L%%6&&,63&"114EEr   c                    d}| j                   j                  dk(  rE| j                         }| j                         }|D ]  }||v s|dz  } | j                  |z
  | _        | j                   j
                  dk(  rI| j                         }| j                         t        fd|D              }| j                  |z
  | _        y y )Nr   r1   r   c              3   &   K   | ]  }|v  
 y wr  r   )r  r  r  s     r   r  z.LeaveRequest.exclude_leaves.<locals>.<genexpr>c  s      &" "55&r  )rV  r)  r  r  rn  r(  r  r  )r   holiday_countr  r  r  company_leave_countr  s         @r   r  zLeaveRequest.exclude_leavesW  s    --6"224O ..0M"1 '!]2!Q&M' #'"5"5"ED33u<"224O"&":":"<"% &&5& # #'"5"58K"KD =r   c                    | j                   }| j                  }t        j                  j	                  ||      }| j
                  |j                  kD  rM| j
                  |j                  z
  }|j                  | _        d|_        |j                  |z
  |_        || _	        n/|j                  | j
                  z
  |_        | j
                  | _        d| _
        |j                          y )NrU  r   r   )rW  rV  rI  r   r  rn  rd  approved_available_daysrc  approved_carryforward_daysrm  r	  )r   rW  rV  rJ  leaves        r   no_approvalzLeaveRequest.no_approvali  s    &&**(0044'[ 5 
 !?!??''/*H*HHE+:+I+ID(-.O*11E9 - /4D+  ..1D1DD * ,0+>+>D( r   c                 H   t         j                  j                  |       }|j                  d      j                  d      }|j                  d      j                  d      }g }|D ]  }|j	                  |j
                          |j                         r	||||d}|S d}|S )Nr  F)is_approvedr  T)r  r   r   	approvals)r  r   r   r  r|  r  r   )	r   r   r   r  requested_queryapproved_queryr  r  results	            r   multiple_approvalszLeaveRequest.multiple_approvals  s    199@@RV@W	#**u*=FFzR"))d);DDZP  	0GOOG../	0$*,&	F  Fr   c                 @   t        t        j                  dd       }|rt        j                  j                  |j                        j                         }t        j                  j                  | |j                        j                         }|r|j                   S yy )Nr  )employee_user_id)r  r  T)r  r   r  r   r   r   r  r  r  r   r  )r   r  employeecondition_approvals       r   r  zLeaveRequest.is_approved  s    -<<iN''...MSSUH!>!F!F!M!M!%(++ "N "eg  "-9999 r   c                 &   | j                   dk(  r t        |   |i | | j                          y t	        t
        j                  dd       }|rDt        |       t        j                  |t        d      j                  | j                                y y )Nr   r  z(The {} leave request cannot be deleted !)rm  r  r  r  r  r   r  r   r	   warningr   format)r   r   r   r  r  s       r   r  zLeaveRequest.delete  s|    ;;+%GND+F+ ++-1@@)TRGw'  @AHHU r   c                    t         j                  j                  t        | j                        t        d      z  t        d      z        }|D ]  }|j                         |_         t         j                  j                  |dg       y)zH
        Update the leave clashes count for all leave requests.
        r   r   r  r   r  N)rp  r   excluder   r   r  r  bulk_update)r   leave_requests_to_updateleave_requests      r   r  z'LeaveRequest.update_leave_clashes_count  s}     $0#7#7#?#?MA[11AZ4HH$
  6 	TM0=0Q0Q0SM-	T 	(($'<&=	
r   c                    t         j                  j                  | j                        }|j	                         r| j
                  dvrt        j                  j                  | j                        j                  t        | j                  j                  j                        t        | j                  j                  j                        z  t        | j                  j                  j                        z  | j                  | j                        j                  t        d	      t        d
	      z        }|j!                         S y)z
        Method to count leave clashes where this employee's leave request overlaps
        with other employees' requested dates.
        r  r  r   ).employee_id__employee_work_info__department_id)0employee_id__employee_work_info__job_position_id)rO  r  r   r  r   r   )r   r   r   rW  r   rm  rp  r   r   r   r  r  r  r   r8  r7  r   )r   r  overlapping_requestss      r   r  z LeaveRequest.count_leave_clashes  s   
 ,33::tGWGW:X	$++5N"N$$,,,8KOK[K[KnKnK|K| MQM]M]MpMp  NA  NA DHDTDTDgDgDrDr
 %)MM"&//   +.*1EEF# !( (--//r   )NN)<r   r   r   r   r*  r   rw  r   rW  r   r+  rV  r$  r7  r  	BREAKDOWNr  r8  r  r  rn  r#  r  	TextFielddescription	FileField
attachmentLEAVE_STATUSrm  r   r   r  r  r  reject_reasonr$   r#   rx  
created_byr   r   r   r  r  r  r  r  r  r  r	  r   r  r  r  r  r  r  r  r  r,  r-  s   @r   rp  rp    s   #&##FNN:K &F%%V^^!L/M "!!u1\?KJ+6++-.	  vTAjMRH)))+,	 'V&&A.>,?N .&--"7 8 #&""-0@SQK!!!*|_	J Vx[	F &V%%1^+<N 0f//:!2!2!21!=$F$$?!3M "
G #""..,|_J $KG L,0"-#^@D=~F L$,$

 r   rp  c                   2    e Zd Z ej                  d      Zy)LeaverequestFilezleave/request_files)r   N)r   r   r   r   r+  filer   r   r   r1  r1    s    6&;<Dr   r1  c                       e Zd ZdZ ej
                  eej                        Z ej
                  e	ej                        Z
 ej                  ed      Z ej                  d ed      d      Zdefd	Zy
)LeaverequestCommentz#
    LeaverequestComment Model
    r   Tr   Commentr  r   r   r   returnc                     | j                    S r  commentr  s    r   r  zLeaverequestComment.__str__      ,, r   N)r   r   r   __doc__r   r*  rp  rw  
request_idr   rW  ManyToManyFieldr1  filesr)  r   r<  r]  r  r   r   r   r4  r4    su     #""<6>>JJ#&##HGK"F""#34@EfDq|PSTG! !r   r4  c                       e Zd Z ej                  eej                  d      Z ej                  eej                  d      Z
 ej                  dd      Z ej                  ej                        Z ej"                  d      Z ej&                  ddd	
      Z ej*                  ded      Z ej"                  dd      Z edeg      Z ed      Z G d d      Zd Z fdZ  fdZ!d Z"d Z# xZ$S )LeaveAllocationRequestrM  r  r   Tr   r   r   r  r   r  r   r   r   r   r   r   rP  rQ  rO  r   c                       e Zd ZdgZy)LeaveAllocationRequest.Metar   Nr   r   r   r   r   rH    r   r   r   c                 R    | j                    d| j                   d| j                   S Nz| rW  rV  r   r  s    r   r  zLeaveAllocationRequest.__str__  s+    ""#2d&8&8%9DGG9EEr   c                 $    t        |   |i | y r  )r  r	  r
  s      r   r	  zLeaveAllocationRequest.save  s    d%f%r   c                 2    t        |   |i | d| _        y )NF)r  __init__skip_historyr
  s      r   rN  zLeaveAllocationRequest.__init__  s    $)&)!r   c                     t        |       S r  r!   r  s    r   r  zLeaveAllocationRequest.tracking  r  r   c                     	 t        |       dd }|D ]#  }|d   dk(  s|d   D ]  }|d   dk(  s|c c S  % y#  Y yxY w)zS
        This method is used to return the tracked history of the instance
        N   r  Changeschanges
field_namern  r!   )r   	historiesrx  updates       r   allocate_trackingz(LeaveAllocationRequest.allocate_tracking  sc    
	 r*I$ *6?i/"))"4 *!,/3CC#)M**
	s   9 9 9 9 =)%r   r   r   r   r*  r   r+  rV  r   rw  rW  r  rn  r$  r   r   r  r)  r*  r+  r,  r  LEAVE_ALLOCATION_STATUSrm  r.  r$   r#   rx  r   r   r   r  r	  rN  r  rX  r,  r-  s   @r   rC  rC    s   %F%%V^^,M $&##FNNK 'V&&T=N%V%%hll;N"&""c2K!!!)AJ V6F %F$$4C@M"
G $KG F&"r   rC  c                       e Zd ZdZ ej
                  eej                        Z ej
                  e	ej                        Z
 ej                  ed      Z ej                  d ed      d      Zdefd	Zy
)LeaveallocationrequestCommentz-
    LeaveallocationrequestComment Model
    r5  Tr6  r7  r  r8  r9  c                     | j                    S r  r;  r  s    r   r  z%LeaveallocationrequestComment.__str__2  r=  r   N)r   r   r   r>  r   r*  rC  rw  r?  r   rW  r@  r1  rA  r)  r   r<  r]  r  r   r   r   r[  r[  (  sv     #""#9V^^TJ#&##HGK"F""#34@EfDq|PSTG! !r   r[  c                       e Zd Z ej                         Z ej                  d      Z ej                  d      Z ej                  e
ej                        Z ej                  eej                        Zy)r  Fr   r5  N)r   r   r   r   r#  r  r  r  is_rejectedr*  rp  rw  r  r   r  r   r   r   r  r  6  sg    "v""$H%&%%e4K%&%%e4K(v((P"""8v~~FJr   r  c            	          e Zd Z ej                  d      Z ej                   ed            Z ej                   ed            Z	 ej                  e ed      ej                        Z ej                  e ed      d	 ed
            Z ej"                  d	 ed            Z ej                  e ed      dd	 ed            Z ej                  e ed      dd	 ed            Z ej,                  d	 ed      d      Z ej                  ed	d	ej                   ed            Z ed      ZdefdZy)rz     rE  r1  r2  r3  r   )r   r   r   TzxIf no job positions are specifically selected, the system will consider all job positions under the selected department.)r   r   	help_textz!Enable to select all Leave types.)r   ra  zSpesific leave typesspesific_leave_typez(Choose specific leave types to restrict.)r   rK  r   ra  zExclude leave typesexcluded_leave_typez/Choose leave types to exclude from restriction.r  r  r8  r   )r   r   r   r   r   r   r9  c                     | j                    S r  )titler  s    r   r  zRestrictLeave.__str__k  s    **r   N)r   r   r   r   r  re  r$  r   r7  r8  r*  r   rw  r  r@  r   r   r  r  r   r  r  r)  r*  r   r   r   r   r]  r  r   r   r   rz  rz  >  ss   F,E!!!q?JvQz];H"""<FNNJ *6))~& G
	L &&%%"E FK 2611-.*>? 1&00,-*EF #&""- 0SK #""..y\J $,GG r   rz  
attendancec                       e Zd Z ej                  eej                  d      Z ej                  eej                  d      Z
 ej                  dd      Z ej                  dd      Z ej                  ej"                  	      Z ej&                  d
      Z ej*                  ded      Z ej&                  dd
      Z edeg      Z ed      Z G d d      Zd Zd Z d Z! fdZ" xZ#S )CompensatoryLeaveRequestrM  r  r   zattendance.Attendance
Attendancer2  TrD  r   r  rE  r   r   r   rF  rP  rQ  rO  r   c                       e Zd ZdgZy)CompensatoryLeaveRequest.Metar   Nr   r   r   r   r   rk    s	    wHr   r   c                 R    | j                    d| j                   d| j                   S rJ  rK  r  s    r   r  z CompensatoryLeaveRequest.__str__  s+    &&'r$*<*<)=RyIIr   c                     t         j                  j                  | j                  | j                        \  }}|xj
                  | j                  z  c_        |j                          y )NrY  )rI  r   get_or_createrW  rV  rd  rn  r	  )r   rJ  createds      r   assign_compensatory_leave_typez7CompensatoryLeaveRequest.assign_compensatory_leave_type  sZ    '5'='='K'K ,,"00 (L ($OW **d.A.AA*  "r   c                    t         j                  j                  | j                  | j                        j                         rt         j                  j                  | j                  | j                        j                         }|j                  | j                  k  r=d|_        t        d|j                  | j                  |j                  z
  z
        |_
        n|xj                  | j                  z  c_        |j                          y y )NrY  r   )rI  r   r   rW  rV  r   r  rd  rn  ru  rc  r	  )r   rJ  s     r   exclude_compensatory_leavez3CompensatoryLeaveRequest.exclude_compensatory_leave  s    %%,, ,,"00 -  fh #1"8"8"?"? $ 0 0"&"4"4 #@ # %'   #11D4G4GG56O28;'99..1O1OOQ9O5 $22d6I6II2$$&#r   c                     t         j                  j                  d      j                         | _        t        |   |i | y )NTr   )r   r   r   r  rV  r  r	  r
  s      r   r	  zCompensatoryLeaveRequest.save  sA    !*!2!2!9!9&* ": "eg  GL$)&)r   )$r   r   r   r   r*  r   r+  rV  r   rw  rW  r@  attendance_idr  rn  r$  r   r   r  r)  r*  r  rY  rm  r.  r$   r#   rx  r   r   r   r  rp  rr  r	  r,  r-  s   @r   rh  rh  q  s   )))l
 (f''Z
 /..#%
 +**DA)))(,,?&f&&#6!!!#:K
 )((tD!& 
 ("O
	 		J	#	'(	* 	*r   rh  c                       e Zd ZdZ ej
                  d      Z ej                         Z ej                  e
ej                  d      Zy)LeaveGeneralSettingz
    LeaveGeneralSettings
    Tr   )r   r   N)r   r   r   r>  r   r  compensatory_leaveManagerr   r*  r   rw  r   r   r   r   rv  rv    sD     -,,T:fnnG"""7fnn4PJr   rv  c                       e Zd ZdZ ej
                  eej                        Z ej
                  e	ej                        Z
 ej                  ed      Z ej                  d ed      d      Zdefd	Zy
)CompensatoryLeaverequestCommentz7
        CompensatoryLeaverequestComment Model
        r5  Tr6  r7  r  r8  r9  c                     | j                    S r  r;  r  s    r   r  z'CompensatoryLeaverequestComment.__str__  s    ll^$r   N)r   r   r   r>  r   r*  rh  rw  r?  r   rW  r@  r1  rA  r)  r   r<  r]  r  r   r   r   rz  rz    sz    	 'V&&$

 (f''FNNK&&&'7tD"&""1Y<TWX	%S 	%r   rz  c                   2    e Zd Z ej                  d      Zy)r  Tr   N)r   r   r   r   r  r  r   r   r   r  r    s    !f!!$/Gr   r  c                   <     e Zd ZdZ eee       fd       Z xZS )OverrideLeaveRequestsz@
        Class to override Attendance model save method
        senderc                 4   t        dd      }|j                  |j                  k(  r<|j                  |j                  k7  r#|j                  |_        t
        t        |          t        |j                  |j                        }|j                  dk(  r@|D ]9  }	 |j                  j                  ||j                        j                         r'|j                  j                  ||j                        n |       }|j                  |_        d|_        |j                  |k(  r|j                  dk(  s|j                  |k(  r|j                  dk(  rd	nd
|_        |j                  |k(  r|j                  dk(  s|j                  |k(  r|j                  dk(  rdnd}||_        ||_        |dk(  rdn
t%        d      |_        |j                          < y|D ]8  }|j                  j                  d||j                        j)                          : y#  Y xY w)zC
            Overriding LeaveRequest model save method
            rf  workrecords)	app_labelmodelr   )r   rW  Tr/   r0   r  g        CONFABSAbsentz$Half day Attendance need to validate)is_leave_recordr   rW  N)r   r7  r8  r  r  r  rp  r	  r   rm  r   r   rW  r   r  day_percentagework_record_typer   r   messager  )	r  instance_kwargsWorkRecordsperiod_datesr   
work_entryrm  r  s	           r   leaverequest_pre_savez+OverrideLeaveRequests.leaverequest_pre_save  s0   
 2&mK ##x'8'88//83P3PP.6.K.K+lH24)(*=*=x?P?PQL*,( (D'  +2299%),4,@,@  :   %fh '	 (//66%),4,@,@ 7  "- # 2:1E1E
.59
2  (22d: ( = = M'00D8 ( ; ;} L	 !
 "& #1  (22d: ( = = M'00D8 ( ; ;} L	 #
 "'  7=
3*.
  & %!"#I!J #*
 #)M(V ) D''..(,!$,$8$8 /  fh	s   D5HH)	r   r   r   r>  r   r   rp  r  r,  r-  s   @r   r~  r~    s%    	
 
(<	0@	 
1@	r   r~  r  c                 `    | }fd}t        j                  |      }|j                          y)z9
    post save method to update the available leaves
    c                      	 j                   rHj                  j                  j                  j                         } | D ]  }|j	                           y y # t
        $ r
}Y d }~y d }~ww xY w)N)rV  )rV  rW  rJ  r   r	  	Exception)available_leavesassigneder  s      r   update_leavesz'update_available.<locals>.update_leaves*  sq    	%%#+#7#7#G#G#N#N"*"8"8 $O $  !1 $HMMO$	 &  		s   AA 	A+&A+)targetN)	threadingThreadstart)r  r  r   _senderr  threads    `    r   update_availabler  "  s*     G	 ]3F
LLNr   )mr   loggingr  r  r  r   r   r   dateutil.relativedeltar   django.appsr   django.confr   django.contribr	   django.core.exceptionsr
   django.core.files.storager   	django.dbr   django.db.modelsr   django.db.models.signalsr   r   django.dispatchr   django.utilsr   django.utils.translationr   r   base.horilla_company_managerr   base.methodsr   base.modelsr   r   r   r   r   r   r   employee.modelsr   r   horillar   horilla.methodsr   horilla.modelsr    horilla_audit.methodsr"   horilla_audit.modelsr#   r$   leave.methodsr%   leave.threadingr&   	getLoggerr   loggereqner)   r*   r+   r,   containsr  r(  r%  r  r  r   r  r  r"  ACCRUAL_PLANr-  rY  rF  r   r   r/  r;  rG  rI  r  rp  Modelr1  r4  rC  r[  r  rz  is_installedrh  rv  rz  r  r~  r  r   r   r   <module>r     s        . . 0    # 2 5   8 $ ! 6 > '   > ' 3 ' * B 2 ,			8	$ [[
++
++
++
++""  :1\?#Am$%	
 <
( q{)q{ 	!E(O!E(O!E(O!E(O!E(O!E(O!E(O!E(O!E(O	1U8	1U8	1U8
!:!! ! 	!
 ! ! ! ! ! ! ! ! ! ! !  !!" #!$ %!& '!( )!* +!, -!. /!0 1!2 3!4 5!6 7!8 9!: ;!< =!> ?!@ A!H qx 7AgJ"7&!F)9LMAfI1X; 7
8 ,-.Q'(A9:;   >!23j!J-5PQ !K.!:!K.!:	 !K.!::  	!L/!M
!L/!M
!L/	 	!H+!I,!K.!J-!H+!J-!H+	T Tnl h< h" !d&\ d&NH< HV=v|| =!, !8\ 8v!L !GFLL G.L .b 4\"B*< B*JQ, Q 4\"%, % 0 0 4\"G GT 
)L) *r   